图片性能优化
# 常见 web 图片格式
jpeg/jpg
- 属于栅格图形。一种针对彩色照片的有损压缩图形格式。常用扩展名有 .jpg、.jpeg、.jpe。
- 不适合:线条、文字、图标图形。并且不支持透明度。
- 适合:颜色丰富的照片、彩色图、大焦点图、Banner 图、结构不规则图形。
png
- 属于栅格图形。一种无损压缩的位图图形格式,支持索引、灰度、RGB 三种颜色方案以及 Alpha 通道等特性,最高支持 24 位彩色图像(PNG-24)和 8 位灰度图像(PNG-8)。文件比 jpeg 或者 gif 大,但是很好的保留了图像质量。
- 不适合:彩色图像。因为是无损压缩,彩色图像体积太大。
- 适合:纯色、透明、线条、图标、边缘清晰、有大块相同颜色区域、颜色较少但需要半透明效果的图形。
gif
- 属于栅格图形。一种位图图形格式,以 8 位色(即 256 种颜色)重现真彩色的图像,采用 LZW 压缩算法编码。仅支持完全透明和完全不透明,支持动画效果。
- 不适合:每个像素只有 8 比特,不适合彩色图像。
- 适合:动画、图标
webp
- 一种现代化的图形格式,可以提供无损和有损压缩,能够在一定程度上保证图像质量和比较小的体积。可以插入多帧实现动画效果,可以哦设置透明度。采用 8 位压缩算法,无损的 webp 比 png 小 26%,有损压缩的 webp 比 jpeg 小 25% - 34%,比 gif 有更好的动画效果。
- 不适合:最多处理 256 色,不适合彩色图像。
- 适合:常见图形和半透明图像。
# 使用工具压缩
安装依赖包
# https://github.com/fengyuanchen/compressorjs npm install compressorjs
示例
<input type="file" id="file" accept="image/*" />
import axios from 'axios' import Compressor from 'compressorjs' document.getElementById('file').addEventListener('change', e => { const file = e.target.files[0] if (!file) { return } new Compressor(file, { quality: 0.6, // The compression process is asynchronous, // which means you have to access the `result` in the `success` hook function. success(result) { const formData = new FormData() // The third parameter is required for server formData.append('file', result, result.name) // Send the compressed image file to server with XMLHttpRequest. axios.post('/path/to/upload', formData).then(() => { console.log('Upload success') }) }, error(err) { console.log(err.message) } }) })
# CDN 图片资源服务器压缩
通过图片 url 参数获取不同尺寸和像素的图片,格式:原图地址z宽 x 高.后缀。
- 例如:原图地址
https://xx.com/pic/20210830/xsjvn27v8r/1.png
;需要压缩成 宽 200,高 100。 - 压缩后的图片地址:
https://xx.com/pic/20210830/xsjvn27v8r/1.png_z_200x100.png
。
- 例如:原图地址
图片宽高需要根据设计稿和设备尺寸进行调整并以 100 为一个档位向上取整。
例如:根据 750 尺寸设计稿,图片设计尺寸 120px _ 360px,设备宽度 375px;则计算后的图片尺寸宽度为 120 _ 375 / 750 = 60px,高度为 360 _ 375 / 750 = 180px,以 100 为一个档位向上取整后的尺寸为 100px _ 200px。
因为考虑到宽高取整的误差,所以我们以宽度为基准,高度向上取整后再加一个档位 200 + 100;得到最终压缩图片尺寸为 100px * 300px。
综上,代码图片尺寸为 60px _ 120px,CDN 图片尺寸为 100px _ 300px
# 响应式图片
js 绑定事件检测窗口大小
css 媒体查询
@media screen and (max-width: 640px) { .image { width: 640px; } }
img 标签属性
<img srcset="img-320w.jpg, img-640w.jpg 2x, img-960w.jpg 3x" src="img-640w.jpg" />
# 逐步加载
使用统一图片占位符
使用低质量图像占位符
# 安装 # https://github.com/zouhir/lqip-loader
使用 svg 图像占位符
# 安装 # https://github.com/axe312ger/sqip
# 其他优化
图片懒加载。初始不设置 src,将 data 数据存在 data-src 里,等滚动到当前图片时再将 data-src 的值赋值给 src
使用字体图标和雪碧图
小图片转码成 base64 可以减少资源请求次数