浏览器IMG图片原生懒加载loading=”lazy”实践指南
source link: https://www.zhangxinxu.com/wordpress/2019/09/native-img-loading-lazy/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8981
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
一、Lazy loading Chrome 76支持啦
年初就听说Chrome浏览器的IMG图片和IFRAME框架会支持原生懒加载特性,使用loading="lazy"
语法。
盼星星盼月亮,终于,兼容性表中的格子绿啦,绿色真好,Chrome76支持!
我一看自己的浏览器,嘿嘿嘿,已经升级到最近版本,兼容性足够了,可以玩起来啦:
二、懒加载特性的研究
如果你想要让一张图片在靠近浏览器视窗的时候才加载,下面代码就可以了:
<img src="./example.jpg" loading="lazy" alt="zhangxinxu">
无需任何其他的JavaScript代码就可以实现懒加载功能。
眼见为实,您可以狠狠地点击这里:图片原生懒加载lazy loading演示demo
demo页面共有30张 180*180的垂直展示的图片。
我们打开控制台,刷新页面,可以看到加载了有17张图片,剩下的13张没有加载。
居然加载了17张图片,这个数量远远超出了自己的预估!
因为按照demo页面现在的布局,一屏只能显示4张图片,现在一口气加载了17张,难道是加载4屏高度以内的图片素材?
于是我把页面屏幕显示高度变小,再刷新看看,结果如下:
可见加载素材的个数确实和屏幕的可用高度有关,但是并不是按照屏幕高度比例来计算的,迷茫了,没办法,看看规范文档,里面是怎么说的,然而并没有找到相关信息,很可能加载的细节是浏览器厂商自己决定的。
因此,可以得到第一个结论:
1. Lazy loading加载数量与屏幕高度有关,高度越小加载数量越少,但并不是线性关系。
疑问:与网速有关?
难道与网速有关,为了快速滚动滚动条的时候有更好的体验,而不会出现空白占位?
我又把网速调慢测试了下,结果发现果然有关!
在慢网速环境下,加载图片数量更多了,为了避免误差,我反复对比测试,证实了这个结论:
2. Lazy loading加载数量与网速有关,网速越慢,加载数量越多,但并不是线性关系。
例如,在默认状态下,图片加载数量稳定在16个,但是,如果是Fast 3G,则加载数量稳定在21个:
如果是Slow 3G,则加载数量稳定在29个:
用户行为与加载测试
当我们滚动屏幕的时候,没有加载的图片开始按照位置依次加载了,没有任何等待和缓冲。
因此可以得到结论:
3. 滚动即会触发图片懒加载,不会说滚动一屏后再去加载。
另外,测试的时候还发现另外一个现象:
4. 窗口resize尺寸变化也会触发图片懒加载,当屏幕高度从小变大的时候。
例如我们把控制台从下方变到右侧,此时浏览器高度图片变高,会发现又多了几个图片请求:
滚动记忆与跳过加载?
浏览器普通刷新的时候会记住上一次滚动的位置,如果页面之前滚动位置是在很下面,这个时候页面刷新,那么开头那些图片会不会不加载呢?
我测试了下,结果果不其然,开始的图片并不会加载,只会加载下面的图片,看来浏览器还是挺聪明的。
5. 根据滚动位置不同,Lazy loading会忽略头尾的图片请求。
三、语法和参数
HTML loading
属性支持的值除了'lazy'
还有下面这几个:
如果HTMLImageElement或者HTMLIFrameElement元素没有显式地设置loading
属性或者loading
属性的值不合法,则都被当作'auto'
处理。
四、与JS有关的实践指南
1. 如何判断当前浏览器是否支持loading=”lazy”?
下面三种方法都可以:
var isSupportLoading = 'loading' in document.createElement('img');
var isSupportLoading = 'loading' in new Image();
var isSupportLoading = 'loading' in HTMLImageElement.prototype;
2. 如何获取loading属性值
假设<img>
元素的DOM变量名是img
,则该图片元素的loading
属性值直接下面语法就可以获取了:
var attrLoading = img.loading;
如果浏览器并不支持原生的loading
懒加载,则会返回undefined
,例如在Firefox浏览器下:
3. loading自定义扩展并不会覆盖
HTMLElement.prototype.loading = function () {}; img = document.querySelector('[loading]'); img.loading;
我们在HTMLElement原型上扩展一个名为loading
的函数,并不会影响图片元素原生的loading
属性。
但是,对于不支持的浏览器,例如Firefox,则明显受到了影响:
4. 如何兼容不支持的浏览器?Polyfill?
GitHub上有个项目用来兼容原生的懒加载loading属性的,项目地址:https://github.com/mfranzke/loading-attribute-polyfill
我看了下原理,是需要把图片HTML代码放在<noscript>
标签中:
<noscript class="loading-lazy"> <img src="example.jpg" loading="lazy" alt="zhangxinxu" width="250" height="150" /> </noscript>
我头上立马出现了一连串的问号,恕我愚钝,这是个锤子效果的polyfill,无JavaScript特性下表现确实符合规范,但是有JavaScript的时候,你这串代码基本上就没有实用价值,因为图片素材本身是占据尺寸大小的,与布局密切相关的,放在<noscript>
标签中,占据宽高尺寸都是0,体验一团糟,完全不能接受。
唯一可行方案是HTML代码输出的时候,根据浏览器(最好JS对象判断)输出不同的HTML代码,例如支持native loading的HTML这样:
<img src="example.jpg" loading="lazy" alt="zhangxinxu" width="250" height="150">
不支持的这样:
<img data-src="example.jpg" loading="lazy" alt="zhangxinxu" width="250" height="150">
然后再使用传统的JavaScript懒加载滚动加载实现即可。
五、研究与实践结果总结
最后,总结下,原生懒加载的5个行为特性:
- Lazy loading加载数量与屏幕高度有关,高度越小加载数量越少,但并不是线性关系。
- Lazy loading加载数量与网速有关,网速越慢,加载数量越多,但并不是线性关系。
- Lazy loading加载没有缓冲,滚动即会触发新的图片资源加载。
- Lazy loading加载在窗口resize尺寸变化时候也会触发,例如屏幕高度从小变大的时候。
- Lazy loading加载也有可能会先加载后面的图片资源,例如页面加载时滚动高度很高的时候。
与JavaScript有关的几个行为特征:
- 判断浏览器是否支持原生loading,最好使用
'loading' in XXX
判断。 - 获取loading属性值可以直接img.loading;
- 原生loading不可写,例如HTMLImageElement.prototype.loading会报错Illegal invocation。
- Polyfill就是场梦,只能等浏览器支持。
还有1分钟24:00,嘿嘿嘿。
节前最后一天,赶一篇还算前沿的研究小文,以此来祝愿大家国庆节过得开心快乐,快乐开心。
对了,我的新书《CSS选择器世界》上市了,国庆回来记得买一本支持下,恩……不对,买一本让自己CSS技术提高下。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK