加载页面时图片一直是流量的大头,过多的图片会严重影响页面的加载速度,针对图片的性能优化方法有诸如 base64、雪碧图等等,延迟加载也是其中一种普遍使用的方法。延迟加载即图片的懒加载或惰性加载,当页面初次加载时只加载显示可视区域的图片,页面滚动时,图片进入了可视区域才会进行资源的加载。过去我们一直通过 js 来实现图片的延迟加载,而 chrome75 的到来将原生支持该功能!其实去年 2 月份 Chrome 就首次提出内置的图片和 iframe 延迟加载机制,并在 8 月的 Canary 版本中加入实验性功能对其进行了测试,最近 Google 技术经理 Addy Osmani 已经宣布今年 5 月底 Chrome 75 将会默认开启延迟加载的功能。
浏览器启用实验性功能
对该功能进行体验和测试需要:
下载最新版本 Chrome Canary。
在 chrome://flags 中将 Enable lazy image loading 和 Enable lazy frame loading 设置为 Enabled。
重启浏览器。
loading 属性
Loading 属性控制浏览器是否延迟加载屏幕外的图像和 iframe:
lazy:对资源进行延迟加载。
eager:立即加载资源。
auto:浏览器自行判断决定是否延迟加载资源。
默认效果(不设置该属性)和 loading=auto 的效果保持一致。需要注意的是,若浏览器决定该资源适合延迟加载,则需要避免页面不正常显示和影响用户体验。
检测属性支持
判断浏览器是否支持 loading 属性(有坑,文章后面会说):
if (‘loading’ in HTMLImageElement.prototype) {
// 浏览器原生支持 `loading` 属性..
} else {
// 通过 js 实现
}
浏览器兼容
需要使用例如 data-original 这样的属性名标记资源地址(而不是 src、srcset 或 <source>),以避免在不支持该属性的浏览器中立即加载资源:
<img loading=”lazy” data-original=”pic.png” class=”lazy” alt=”.” />
若浏览器支持 loading 属性,则把 data-original 替换为 src;若不支持则使用回原来延迟加载的方法:
const images = document.querySelectorAll(“img.lazy”);
if (‘loading’ in HTMLImageElement.prototype) {
images.forEach(img => {
img.src = img.dataset.original;
});
} else {
const LazyLoad = await import(‘/lazyload.min.js’);
let lazyLoadInstance = new LazyLoad({
elements_selector: “img.lazy”
});
}
图片支持类型
看到这个新功能后本来有个想法是,可以结合 SVG 注入器实现 SVG 的延迟加载:
<img loading=’lazy’ src=”warning.svg” onload=”SVGInject(this)” />
但发现对于 SVG 类型文件,延迟加载并没有生效:经个人不完全测试,以下为图片类型的支持程度:
图片类型
是否支持
JPEG
支持
GIF
不支持
PNG
支持
APNG
不支持
SVG
不支持
重复请求
需要注意的是,Chrome 会在页面加载时请求需要延迟加载图片的前 2048 个字节,当用户即将滚动到图片时,Chrome 会再次请求剩余的图片字节(不会影响该图片的 onload 事件)。若服务器支持范围请求,则会在前 2048 个字节中包含图片尺寸,浏览器会生成 / 展示相同大小的占位:
各方态度
火狐:Firefox 的一位工程师表示,Mozilla 目前还没有任何计划实现 Chrome 的延迟加载方案。
Microsoft Edge:新的 Edge 浏览器使用了 Chromium 75 内核,经下载泄露版本测试,该版本在 edge://flags/ 中开启实验性功能,可支持延迟加载,且也会重复请求资源,但 HTMLImageElement.prototype 无 loading 属性,只有 load 属性,需进行区分判断处理。
Safari:一位 WebKit 开发者提到,Apple 对这类功能很感兴趣:
其他:在 WICG 上关于原生支持延迟加载图片的讨论。
总结
在原代码的基础上更新兼容新功能并不复杂,但在启用新功能前可能需要进一步的思考,比如若对所有图片设定 loading=”auto”,某些被延迟加载的图片是否会影响用户体验的流畅性?浏览器对图片进行延迟加载的判断与决定是否会影响页面性能?对大量图片进行延迟加载,浏览器会先请求所有延迟加载图片的前 2048 个字节,在弱网环境下是否会卡在这个阶段反而耽误了首屏图片的加载?其他浏览器是否会遵循这种规范?
emmm 虽然问题有点多但新功能还是可以带来新玩法~比如以后支持 SVG 后可对其进行延迟加载,设定 loading=”eager” 可对首屏重要的大图优先进行加载,对于广告(iframe 或图片)的数据统计可更加精准(设定延迟加载并在 onload 事件中统计)…
参考
AddyOsmani.com – Native image lazy-loading for the web!Firefox will support image lazy loading for new tab page | ZDNetTwitter 上原讨论贴