前端性能优化 - 图片的优化
Google Web Fundamentals的说法:
图片优化既是一门艺术,也是一门科学,图片优化是一门艺术,是因为单个图片的压缩不存在最好的特定性方案,而图片优化之所以是一门科学,是因为许多开发得很出色的方法和算法可以明显减小图片的大小。要找到图片的最优设置,需要按照许多维度进行认真分析:格式能力、编码数据内容、像素尺寸等。
1. 图片格式
我们经常听到的词语包括矢量图、标量图、SVG、有损压缩、无损压缩等等,我们首先说明各种图片格式的特点
格式 | 压缩方式 | 透明度 | 动画 | 浏览器兼容 | 适应场景 |
JPEG | 有损压缩 | 不支持 | 不支持 | 所有 | 复杂颜色及形状、尤其是照片 |
GIF | 无损压缩 | 支持 | 支持 | 所有 | 简单颜色,动画 |
PNG8 | 无损压缩 | 256色 + 支持透明 | 不支持 | 所有 | 需要透明时 |
PNG24 | 无损压缩 | 2^24色 + 支持透明 | 不支持 | 所有 | 需要透明时 |
PNG32 | 无损压缩 | 2^24色 + 支持透明 | 不支持 | 所有 | 需要透明时 |
APNG | 无损压缩 | 支持 | 支持 | Firefox Safari iOS Safari | 需要半透明效果的动画 |
Webp | 压缩程度更好,有损压缩 | 支持 | 支持 | 在ios webview有兼容性问题 ,Chrome Opera Android Chrome Android Browser,安卓全部 | 复杂颜色及形状 浏览器平台可预知 |
Svg | 无损压缩,矢量图 | 支持 | 支持 | 所有(IE8以上) | 简单图形,需要良好的放缩体验 需要动态控制图片特效 |
其中APNG和WebP格式出现的较晚,尚未被Web标准所采纳,只有在特定平台或浏览器环境可以预知的情况下加以采用,虽然均可以在不支持的环境中较好的功能降级,图片格式选择过程如下:
颜色丰富的照片,JPG是通用的选择
- 人眼的结构很适合查看JPG压缩后的照片,可以充分的忽略并在脑中补齐细节
- JPG在压缩率不高时保留的细节还是不错的
- WebP能够比JPG减少30%的体积,但目前兼容性较差
如果需要较通用的动画,GIF是唯一可用的选择
- GIF支持的颜色范围为256色,而且仅支持完全透明/完全不透明
- GIF在显示颜色丰富的动画时可能出现颜色不全、边缘锯齿等问题
如果图片由标准的几何图形组成,或需要使用程序动态控制其显示特效,可以考虑SVG格式
- SVG是使用XML定义的矢量图形,生成的图片在各种分辨率下均可自由放缩
- SVG中可以通过JavaScript等接口自由变换图片特效,可以完成其中部分元素的自由旋转、移动、变换颜色等
如果需要清晰的显示颜色丰富的图片,PNG比较好
- PNG-8能够显示256种颜色,但能够同时支持256阶透明,因此颜色数较少但需要半透明的情景(如微信动画大表情)可以考虑PNG-8
- PNG-24可以显示真彩色,但不支持透明,颜色丰富的图片推荐使用(如屏幕截图、界面设计图)
- PNG-32可以显示真彩色,同时支持256阶透明,效果最好但尺寸也最大
图片尺寸的选择
我们需要分清不同类型的像素:CSS像素和设备像素。一个 CSS像素可能包含多个设备像素。对于图片来说,在高DPI的屏幕上需要使用分辨率更高的图片,如果我们讨论的是Retina,那么就需要2倍分辨率(几乎4倍尺寸)的图片。
我们能够控制的地方是"恰好"显示所需尺寸的图片。例如在屏幕中通过CSS或者标签的wihth/height属性,将一副200x200的图片调整为100x100大小,那么这其中就有(200x200)-(100x100)=30000个像素是浪费的,这占到了图片尺寸的75%!
使用inline-image
小于4kb或者8kb的图片inline-image,减少http损耗
雪碧图
将在同一页面中用到的图片放在一张大图上,通过css定位显示不同的图片,减少http的请求次数
自动优化
自动优化:CDN
使用CDN对图片自动进行优化,我在国外的CDN提供商处很少见到这类服务,倒是国内的两大新秀CDN七牛和又拍在这方面都做了大量工作。其工作方式为,向CDN请求图片的URL参数中包含了图片处理的参数(格式、宽高等),CDN服务器根据请求生成所需的图片,发送到用户浏览器。
七牛云存储的图片处理接口极其丰富,覆盖了图片的大部分基本操作,例如:
- 图片裁剪,支持多种裁剪方式(如按长边、短边、填充、拉伸等)
- 图片格式转换,支持JPG, GIF, PNG, WebP等,支持不同的图片压缩率
- 图片处理,支持图片水印、高斯模糊、重心处理等
七牛云存储的图片处理接口使用并不复杂,例如下面这张原图:
我们通过如下URL请求,裁剪正中部分,等比缩小生成200x200缩略图:
http://qiniuphotos.qiniudn.com/gogopher.jpg?imageView2/1/w/200/h/200
自动优化:Grunt/Gulp/webpck
这里介绍用于图片优化的Grunt组件:grunt-image。前端工程师的重复性工作,例如合并静态资源、压缩JS和CSS文件、编译SASS等都可以使用Grunt等自动化工具批量完成,图片优化也是如此。
grunt-image非常强大,按照作者的介绍,其内部加载的图片优化工具包括了pngquant, optipng, adv*ng, zopflipng, pngcrush, pngout, mozjpeg, jpegRecompress, jpegoptim, gifsicle和svgo。支持批量自动优化PNG, JPG, SVG和GIF,速度也不错,配置方式支持单图片优化和全目录优化
自动优化:Google PageSpeed
Google做事风格比较彻底,看见哪个软件不好用就拿来直接fork出新版本或者干脆重写,对于Web优化,Google发布了了Google PageSpeed这个服务器模块,可以在apache或ngnix中加载,通过在服务器配置文件中进行设置来进行自动化的优化。对于图片格式转换、图片优化甚至图片LazyLoad都有相关选项。这部分展开会非常长,请感兴趣的同学参考Google的手册。