描述
在少量图片/小图加载的时候可能对网站的性能影响不大,但是如果一旦出现对网站产生性能影响的时候就需要考虑一些关于图片优化的方案,所以有了这篇图片优化记录。
优化方式
懒加载
表现出来的效果是”视图内的图片先加载,视图以外的图片在达到某个阈值的时候再加载进来“。
使用intersectionObserver
交叉观察器 API - Web API 接口参考 | MDN;
该API会被传入一个callback, 它会在目标元素达到了某个阈值时被执行,还有一个options用于设置阈值
除了使用这个新API之外,原来通常是通过判断元素和顶部的距离来实现懒加载,但这样会产生大量的任务在主线程,从而在另一方面降低了性能。
预加载
表现出来的效果是”在需要加载图片的时候会更快的显示图片“。因为它预先加载了,现在需要做的就只有显示。
<link rel='reload' href="image.src" as="image" />
;这可以让图片的下载提前,但是解码依然是默认速度。(chrome默认是同步解码)- HTMLImageElement:decoding 属性 - Web API 接口参考 | MDN;img 有一个decoding属性,它的可选值有”async、sync、auto(让浏览器决定用说明方式解码)“;
- async解码是异步的,不会影响其他内容执行。解码完成前将img加入页面,可能会存在一段时间的图片空白,页面不会卡顿
- sync解码是同步的,它的解码在主线程,所以会影响其他执行,表现出来的可能会卡顿,或者其他内容的延迟出现。
- img.decode()这个函数在图片下载和解码的过程都是异步的,不会影响其他的加载,只有当图片加载和解码完成之后才会将图片放到页面上。
const img = new Image();
img.src = "nebula.jpg";
img
.decode()
.then(() => {
document.body.appendChild(img);
})
.catch((encodingError) => {
// Do something with the error.
});
CDN
加快下载图片速度。
img cdn图床还可以根据传入的参数返回指定条件的图片尺寸和质量。
其他细节
在img未设置宽高时会出现如下问题(这个算是页面性能的一项检测指标,CLS:布局修改频率):
图片刚开始没有高度,后面加载解码完成后有高度后会影响其他元素,导致大量元素的回流。
解决:
NextJs的Image组件的解决方法是”在img标签外套一个span标签,在使用组件的时候传入宽高“,这样将内部图片的活动区域进行限制,从而减少布局修改频率。特别是对于SSR渲染来讲,一次布局修改可能对应的就是重新请求HTML。