前端性能优化,不止于前端。
图片认知
无论是 Web 程序还是手机应用,图片往往比文字更能吸引用户,因为人的视线似乎总在第一眼就定位在图片上。
形成这种神奇现象的原因很简单:每个人的大脑里都住着一个”原始人”。
在原始时代,人的大脑需要处理的内容大多和图像有关。
比如,我们的祖先最关心哪里新长出来可以吃的果实,哪里有新的猎物,哪里有猛兽出没、需要避开危险。
这些重要地点和周边环境通过视觉和记忆保存在大脑里,在经历漫长的进化后,人脑逐渐进化出最适宜生存的大脑结构。
因此,人类天生擅长处理和记忆图像。
同样,在网页设计中,图片更能发挥巨大作用,有一个经典说法:一图胜千言。
所以总结图片内容呈现上有以下优点:
- 增加可读性与趣味性,尽可能减少跳出
- 且让文章内容充实,看起来多样化
- 提升搜索引擎抓取收录网站
- 提高用户的浏览体验度
图片类型
下面是我们在项目开发中几乎能接触到的图片分类。
类型解读
- jpg
- png
- gif
- svg
- APNG
- WebP
jpg 全名是 JPEG,JPEG 格式图片以 24位颜色存储单个位图,这是我们在开发过程中最常用的图片格式之一,这种图片的优势是可以对其进行高质量的压缩,比如我们可以将其的图片的品质由 100% 降低 60%,它的体积至少会减少 50% 以上,比如一张 100K 的图片,将其品质降低到 60% 时,它的体积会在 40-50k 之间;而且在压缩后一般我们肉眼也是不易分辨其压缩前后的变化。
png 可移植网络图形格式,这类图片我们常用来做透明和半透明的素材,这种类型的图片可以展示 256 种颜色,每一种颜色都可以做成透明;缺点是体积较大,一般运用于运营型或者商家活动页、抽奖(视觉比较好)的条件下使用。
而 png 类型又分为 png8 和 png24 两种类型。
png8 类型的图片,都最多只能展示256种颜色,所以 png8 格式更适合那些颜色比较单一的图像,例如纯色、logo、图标等;因为颜色数量少,所以图片的体积也会更小;
而 png24 类型的图片,最多可展示的颜色数量多达1600万;所以 png24 所展示的图片颜色会更丰富,图片的清晰度也会更好,图片质量更高,当然图片的大小也会相应增加,比较适合像摄影作品之类颜色比较丰富的图片。
gif 图像互换格式,一般小的 icon 图标或者动画(loading.gif)会使用到,gif 也是能展示256种颜色,但是它只支持全透明和全不透明。
svg 可缩放矢量图形,属于 XML 格式,百度地图就是使用 svg 绘制的,位图当你放大时单位面积内可视的像素点会变少,所以会失真,也就是我们常说的图片模糊,首先 svg 它是一个可以进行计算矢量图,放大和缩小的时每一个像素会根据向量重新计算,固不会失真,并且 svg 的体积很小。
APNG 即 Animated PNG,从字面上理解,这种格式的图像就是一个”会动”的PNG图像, 这个最早是由 Mozilla 的两名程序员设计出来的,当时 Mozilla 放弃了 MNG 图像格式,转而自己开发了 APNG 以存储动态多图文件,他同时具备 jpg 和 png 的优点,唯一的缺点是未被标准采纳,所以没有大规模的使用。
从上图可以看出,在体积一样的情况下,APNG格式的画质相对 GIF 的画质表现更加的清晰和细腻。同时,在24位的情况,由于 PNG 容纳的颜色种类远远多出256种(实际上是1680万种颜色),所以色彩还原更加细腻、真实。
WebP 它是 Google 于2010年提出了一种新的图片压缩格式,WebP 为网络图片提供了无损和有损压缩能力,同时在有损条件下支持透明通道;无损 WebP 相比 PNG 减少26%大小,有损 WebP 在相同的结构相似性下相比 JPEG 减少 25%~34% 的大小,所以它也同时具备 jpg 和 png 的优点。
目前国内外的互联网公司几年前也开始使用,国外的有 Google、Facebook 和 ebay,国内的有淘宝、腾讯和美团等。
至于 WebP 的兼容性,基本支持 IE11+ 和主流的浏览器。
图片使用
说着这么多的图片类型,我们在项目开发中,如何基于性能和用户体验的权衡来选择合适的图片类型呢?
- 如果是颜色丰富的图片,jpg 是通用的选择。
- 如果是较通用的动画,gif 是唯一可用的选择。
- 如果需要清晰的显示颜色丰富的图片,png 是比较好的选择。
- 如果是企业级应用(不考虑兼容性),可以选择 webp。
图片的加载方式
图片的加载方式主要分为小波算法、离散余弦变换算法两种,浏览器根据不同图片选择不同的渲染算法,浏览器通过文件头部读取其压缩算法那,所以更改文件后缀名也不会影响加载的方式。
小波算法
小波算法是以先变模糊后逐渐清晰的一种展现方式。
目前没有发现小波算法的图片,但是业内已经有很多人基于这个概念做了处理,比如知乎。
首先知乎使用了懒加载的概念,当你滑到浏览器或者 app 的可视区内含有图片时,加载一个较小的图片,他们大约会请求一张缩略的 jpg 图,实际上这是直接在代码中写了 img 标签里,浏览器会正常请求;
一旦图片加载了,它们会开始绘制一个 canvas 标签,图片的数据会传递给自定义的 blur 函数,这个函数与 StackBlur 有点相似,但不完全,设置 opacity 动画效果,同时网络开始请求原图。
等原图加载完毕后,于是区域便展示原图,此时 canvas 则会隐藏掉,这几个过程可以通过 CSS3 的 transition 属性从而让整个渐变效果更加流畅,大大的提高用户体验。
离散余弦变换算法
离散余弦变换算法,是从图片的顶部开始,逐行清晰的加载,以至整张图片完整的显示。
比如我博客的旅行记录页面,FSUX之旅行;当你第一次打开,首次加载时,图片的顶部开始,逐步清晰的加载出图片完整的形态,当然第二次加载时,会有秒开的感觉(因为我做了缓存,嘿嘿)
流行做法
CSS3
CSS3 通过提供相同的视觉效果而成为图片的“替代品”,换句话说,在进行 Web 开发时,减少多余的标签嵌套,以及图片的使用数量,意味着用户要下载的内容将会更少,页面加载也会更快。
另外,更少的图片、脚本和 图片文件让 Web 站点减少 HTTP 请求数,这是提升页面加载速度的最佳方法之一。
而使用CSS3制作图形化网站无需任何图片,极大地减少HTTP的请求数量,并且提升页面的加载速度。
当然,这取决于采用CSS3特性来代替什么技术,同样还要看如何使用 CSS3 特性。
例如 CSS3 的动画效果,能够减少对 JavaScript 和 图片的 HTTP 请求,但可能要求浏览器执行很多的工作来完成这个动画效果的渲染,这有可能导致浏览器响应缓慢,致使用户流失。因此,在使用一些复杂的特效时,大家需要考虑清楚。
不过这样的现象毕竟为数不多。其实很多CSS3技术能够在任何情况下都大幅提高页面的性能。就这一条足以让我们使用CSS3。
优势:
- 体积减小。
- HTTP 请求数减少。
- ctrl + 滚轮缩放十分平滑,无锯齿。
- 用 SCSS 写 CSS 的话,尺寸计算其实很方便。
CSS Sprites
CSS Sprites 其实就是把网页中一些背景图片整合到一张图片文件中,再利用 CSS 的 “background-image”,“background- repeat”,“background-position” 的组合进行背景定位,background-position 可以用数字能精确的定位出背景图片的位置。
优点:
- 减少图片的字节
- 减少了 http 请求,从而大大的提高了页面的性能
- 解决了网页设计师在图片命名上的困扰,只需对一张集合的图片上命名就可以了,不需要对每一个小元素进行命名,从而提高了网页的制作效率。
- 更换风格方便,只需要在一张或少张图片上修改图片的颜色或样式,整个网页的风格就可以改变。维护起来更加方便。
建议:
- 不建议大图片合并
- 建议类似图片合并
iconfont
Iconfont 指用字体文件取代图片文件,来展示图标、特殊字体等元素的一种方法。
示例:iconFont
这里以 iconfont的使用 为例
font-face 字体声明:
.css 文件
@font-face {font-family: "iconfont";
src: url('iconfont.eot'); /* IE9*/
src: url('iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('iconfont.woff') format('woff'), /* chrome, firefox */
url('iconfont.ttf') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}
我们可以看到,不同的浏览器调用不同的字体文件。
定义一下Iconfont 的样式:
我们可以通过字体的大小font-size和自体颜色color改变图标的大小和颜色。
.css 文件
.iconfont {
font-family:"iconfont" !important;
font-size:16px;
color:#f00;//红色
}
挑选图标对应的字体编码,应用于页面中:
.html 文件
<i class="icon iconfont"></i>
优点:
- 加载文件体积小。
- 减少 http 请求。
- 可以直接通过 css 的 font-size,color 修改它的大小和颜色,对于需要缩放多个尺寸的图标,是个很好的解决方案。
- 支持一些 css3 对文字的效果,例如:阴影、旋转、透明度。
- 兼容低版本浏览器。
前瞻性做法
响应式动态图片加载(SDK)
- 我们需要一个默认图片
- 屏幕分辨率的信息返回给服务器
- 使用服务器返回的更优质的图片资源
根据不同的分辨率加载不同资源的图片(部分浏览器现已支持)
.html 文件
<picture>
<source src="/path/to/medium-image.png" media="(min-width: 600px)">
<source src="/path/to/large-image.png" media="(min-width: 800px)">
<img src="/path/to/mobile-image.png" alt="image description">
</picture >
系列文章
先占个坑,后续写完。
- 前端性能优化之 DOM 篇 (完)
- 前端性能优化之图片篇(完)
- 前端性能优化之视频篇
- 前端性能优化之资源篇
- 前端性能优化之存储篇
- 前端性能优化之缓存篇
- 前端性能优化之加载篇
- 前端性能优化之 SSR 篇