图片加载优化
1. 问题
elitemba主站 以图片展示为主,启动页面时加载过多图片,图片体积过大,导致等待时间过长。这些图片请求几乎是并发的。在Chrome浏览器,同一域名,最多支持6个请求的并发,其他的请求将会推入到队列中等待,直到6个请求中的一个完成后,队列中的新请求才会发出。
下面列出一些图片加载优化方法。
1. 压缩图片体积
1.1 图片格式
Web图片格式有JPEG/JPG、PNG、WebP、Base64、SVG等。
JPEG/JPG
有损压缩、体积小、不支持透明。当我们把图片体积压缩至原有体积的 50% 以下时,JPG 仍然可以保持住 60% 的品质。此外,JPG 格式以 24 位存储单个图,可以呈现多达 1600 万种颜色。JPG 适用于呈现色彩丰富的图片,在我们日常开发中,JPG 图片经常作为大的背景图、轮播图或 Banner 图出现。
但它处理矢量图形和logo等线条感较强、颜色对比强烈的图像时,人为压缩导致的图片模糊会相当明显。
PNG-8/PNG-24
无损压缩、质量高、体积大、支持透明 PNG是一种无损压缩的高保真的图片格式,8位PNG支持256中颜色,24位可呈现1600万中颜色。考虑到 PNG 在处理线条和颜色对比度方面的优势,我们主要用它来呈现小的 Logo、颜色简单且对比强烈的图片或背景。
SVG
文本文件、体积小、不失真、兼容性好SVG是一种基于XML语法的图像格式,它对图像的处理不是基于像素点,而是基于对图像的形状描述。它的优势是图片可无线放大而不失真。因为SVG是文本文件,我们可以像写代码一样定义SVG,把它写在HTML里、成为DOM的一部分。
Base64
Base64不是一种图片格式,而是一种编码方式,作为小图标解决方案而存在。通过对图片进行baser64编码,我们可以直接将编码结果写入HTML或者CSS,从而减少HTTP请求的次数。
WebP
它于 2010 年被提出, 是Google专为Web开发的一种旨在加快图片加载速度的图片格式,它支持有损压缩和无损压缩。与png相比,WebP无损图像的大小可以缩小26%,比同类jpeg小25-36%。
1.2 图片裁剪
- 阿里云oss图片服务 / 七牛图片服务,提供了图片格式转换、按尺寸裁剪等图片处理功能。配合
lib-flexible
,就可以对不同设备加载不同尺寸的图片。
2. 占位显示
1 | img{ |
pc上,一般我们会为<img>
设置width和height属性来解决图片占位问题。但在移动端,用占位图或min-height来占位,如果与需要加载的图片尺寸差别很大,会出现页面的内容跳动,这也不是我们想要的。
3. 懒加载
滚动到可视区域后再去加载图片
3.1 原理
将页面中<img>
的src
指向一张默认图,然后定义data-src
指向真实的图片。1
2<!-- 注意: 图片要指定宽高 -->
<img src="default.jpg" data-src="http://www.elitemba.cn/static/images/1.png">
当载入页面时,先把可视区域内的<img>
标签的data-src
属性值赋给src
。然后监听滚动事件,同理修改可视区域的图片的src值。
1 | var img = document.getElementsByTagName('img'); |
3.2 节流函数
当函数绑定在scroll
事件上,页面滚动时,函数会被高频触发,这非常影响浏览器的性能。这时需要限制触发频率。
节流函数: 只允许一个函数在n秒内执行一次。
1 | // fun 要执行的函数 |
3.3 去抖函数
让函数延迟执行。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function debounce(fn, delay){
let time = null;
return function(){
let context = this;
let args = Array.prototype.slice.call(arguments);
clearTimeout(time);
timer = setTimeout(function(){
fn.apply(context, args)
}, delay)
}
}
// 让函数延迟500s执行
window.addEventListener("scroll", debounce(lazyload, 500))
4. 骨架屏
骨架屏可以理解为当数据还未加载进来前,页面的一个空白版本。页面渲染完成之前,用户会看到当前页面的大致骨架。
下面的示例图,第一个是骨架屏,第二个是菊花图,第三个无优化。
生成骨架屏的方式:
- 手写HTML,CSS定制骨架屏,但是维护成本高
- 使用图片作为骨架屏: 小米商城的移动端页面
- 自动生成并自动插入静态骨架屏 page-skeleton-webpack-plugin
5. 渐进式图片加载
知乎会用低分辨的模糊图片来做预览图,代替懒加载图片时用的logo占位图,预览图大小在2kb-3kb之间。