加载页面时图片一直是流量的大头,过多的图片会严重影响页面的加载速度,针对图片的性能优化方法有诸如base6四、雪碧图等等,延迟加载也是其中一种广泛使用的方法。延迟加载即图片的懒加载或惰性加载,当页面初次加载时只加载显示可视区域的图片,页面滚动时,图片进入了可视区域才会进行资源的加载。
过去咱们一直经过js来实现图片的延迟加载,而chrome75的到来将原生支持该功能!其实去年2月份Chrome就首次提出内置的图片和iframe延迟加载机制,并在8月的Canary版本中加入实验性功能对其进行了测试,最近Google技术经理Addy Osmani已经宣布今年5月底Chrome 75将会默认开启延迟加载的功能。javascript
对该功能进行体验和测试须要:java
Loading属性控制浏览器是否延迟加载屏幕外的图像和iframe:android
默认效果(不设置该属性)和loading=auto的效果保持一致。须要注意的是,若浏览器决定该资源适合延迟加载,则须要避免页面不正常显示和影响用户体验。git
判断浏览器是否支持loading属性(有坑,文章后面会说):github
if ('loading' in HTMLImageElement.prototype) { // 浏览器原生支持 `loading` 属性.. } else { // 经过js实现 }
须要使用例如data-original这样的属性名标记资源地址(而不是src、srcset或<source>),以免在不支持该属性的浏览器中当即加载资源:web
<img loading="lazy" data-original="pic.png" class="lazy" alt="." />
若浏览器支持loading属性,则把data-original替换为src;若不支持则使用回原来延迟加载的方法:chrome
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个字节中包含图片尺寸,浏览器会生成/展现相同大小的占位:服务器
各方态度
在原代码的基础上更新兼容新功能并不复杂,但在启用新功能前可能须要进一步的思考,好比若对全部图片设定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上原讨论贴