原生懒加载 loading=”lazy” 有多香?我用了五分钟后,默默地删掉了以前的懒加载插件

2026-08-19 0 859

开发一个图文详情页,里面足足有四十多张产品图。客户要求首屏别卡,我自然第一个想到“懒加载”。搁以前,我要么引入一个lozad.js,要么自己用IntersectionObserver封装一个图片懒加载。但这次多翻了一下文档,发现HTML早就内置了懒加载支持——一个属性而已。一试之下,我赶紧把以前写的那些懒加载代码删了,真的一行JS都不用写了。

一行代码实现图片懒加载

原生懒加载的用法简单到不好意思说,就是在<img>标签上加一个loading="lazy"属性。

<img src="product-01.jpg" alt="产品图" loading="lazy">

就这么简单。浏览器会自动判断这张图片是否在视口附近。如果不在,就暂时不下载图片。等用户滚动到快要看到这张图时,浏览器再自动去拉取。它能省下大量带宽,页面初始加载速度自然变快。

不只能给图片用,iframe也能懒加载

你不知道的是,这个属性同样适用于<iframe>。比如页面里嵌入了一个视频播放器或地图,它可能非常重,直接影响首屏渲染。给iframe加上loading="lazy",它就不会在页面打开时立刻加载,而是等用户滚动到那个iframe附近才开始加载。

<iframe src="https://map.example.com/embed" loading="lazy"></iframe>

这太适合那些页面顶部是正文、底部才放地图的博客文章了。以前我还会用js去动态设置src,现在一个属性解决。

浏览器是怎么知道该不该加载的

你可能会好奇,浏览器内部怎么判断“快到了”?其实Chrome的做法是在图片元素进入视口前一定距离(比如1250px)时开始加载。这个距离是隐藏阈值,不能手动改。但它内部就是用IntersectionObserver来检测元素与视口的交叉情况的。这也意味着,你不用再去管理监听器、又得优化性能,完全原生。

踩坑一:首屏图片不能加lazy

我把首屏的英雄图也加了loading="lazy",结果打开页面时它还在浏览器视口里,浏览器认为它需要立刻加载,但依然会有一些额外判断时间。后来发现,首屏图片一旦加lazy,在部分浏览器里可能会延迟加载,造成首屏白板。正确做法是:首屏或接近首屏的图片不要加lazy,只给那些真正在视口较远的图片加。

踩坑二:没有height或比例的时候,页面会跳

懒加载的图片如果不设置宽高,在加载之前占位空间是0。当图片加载完成,高度突然撑开,下面的内容会被挤下去,造成页面跳动,用户体验非常差。尤其是文章里穿插的图,极其明显。所以一定要给图片设置固定的宽高。比如这样:

<img src="pic.jpg" width="600" height="400" loading="lazy">

如果不知道比例,可以用CSS的aspect-ratio来占位。但为了保持不写样式,我这里只提一下,你实际用的时候记得加上。

踩坑三:背景图片不支持loading=lazy

我有一张大背景图是通过CSS的background-image加载的,想当然给它所在的div加了loading="lazy",结果一点用都没有。浏览器只认<img><iframe>,对背景图片根本不理会。如果你要对背景图做懒加载,只能自己写JS或者用别的方式。所以我才说,原生懒加载并不是全能的。

踩坑四:滚动速度过快时,可能会漏加载

有一次我快速从页面顶部滚到底部,几十张图片瞬间出现在视口里,结果有好几张图片没有成功加载,显示成了一个破图。这在慢速网络下更容易发生。原因是浏览器可能仍然在排队下载前面的图片,而后面的图片又同时在多个视口区域出现,于是被浏览器的并发策略排到了后面,甚至可能因连接不足而延迟。解决办法是:不要对大量图片同时用lazy,尤其列表中图片过多时。也可以把关键的图片预加载或不用lazy。不过这个情况在Chrome出现概率不高,但我确实遇到了。

踩坑五:loading=lazy与懒加载脚本的冲突

如果你像很多老代码一样,在图片上同时加了自定义懒加载class(比如lazyload),并且脚本会把data-src替换成src,那你要小心了。当浏览器检测到loading=”lazy”时,它可能因为图片尚未滚动到视口而不去加载你的data-src,但你的脚本又没触发,结果图片永远不显示。最好的做法是:如果你已经用了原生loading,就彻底移除那些自定义懒加载逻辑,别两个混着用。

踩坑六:老浏览器不支持,但不用太担心

我在Safari 14的测试机上试了一下,loading属性确实不支持,但Safari 15.4以上已经支持。其他浏览器老版本也有不支持的,但现在已经2025年,支持度已经非常好了。如果你非要去兼容很老的浏览器,可以加一行JS检测,如果不支持就动态引入IntersectionObserver的方案。但说实话,真的没必要了。

怎么验证它到底有没有生效

你可以打开浏览器的开发者工具,切到Network标签,然后刷新页面,观察图片的请求列表。能看到滚动之前,视口外的图片一直在“待加载”状态,当你滚动到它们附近时,网络列表中会新增对应的图片请求。如果你发现所有图片一开始就全部加载了,那就是没生效,检查一下是不是把loading写错了,或者图片根本在首屏。

有时候图片虽然加了lazy,但如果它离视口太近(比如就差300px),浏览器也会立刻加载。这是正常的,因为浏览器认为它马上就会可见,没必要懒。

如果只给图片加还不够,那iframe怎么办

iframe加loading=”lazy”同样支持。但需要注意,iframe一般用于嵌入第三方内容,比如广告。有些广告脚本会动态修改iframe的src,这可能导致loading属性失效。所以对第三方嵌入,如果需要懒加载,最好还是用JS控制src,不要依赖原生了。

一个更稳妥的fallback方案

我不需要等你兼容,但多学一手总没错。用IntersectionObserver实现一个极简的图片懒加载,兼容古老浏览器,同时也能处理背景图片:

const lazyImages = document.querySelectorAll('img[data-src]');

const observer = new IntersectionObserver((entries) => {
    for (const entry of entries) {
        if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.dataset.src;
            observer.unobserve(img);
        }
    }
});

lazyImages.forEach(img => observer.observe(img));

但说真的,当我看到这个代码量,再看看原生loading一行搞定,我决定以后新项目全部用原生。除非有背景图需求。

配合height/width预设,真的丝滑

我在项目里把图片的宽高写死,并且在图片外面包了一个div,这样懒加载时占位稳定。当用户滚动到那张图时,浏览器加载完成只是换了个src,完全看不出跳动。整个过程没什么技术含量,全是浏览器替我干的。

说个真实测试:图片加载减少70%

我用一个包含30张图片的页面测了一下,初始加载的图片从30张变成了8张,剩余的都是滚动到哪加载到哪。页面load事件提前了大约1.2秒。注意,这里并不是说图片都不加载了,而是延迟加载,总流量没少,但用户感知的加载速度快了。

总结

原生loading="lazy"是我最近最想分享的一个HTML特性。零成本、高效、完全内置。有了它,我删掉了自己维护了很久的懒加载脚本。如果你还在为页面图片数量发愁,不妨先给一张图加上loading="lazy"看看效果。但要记住,它不是万能的,背景图不支持,首屏别乱用,同时要预留宽高。用对了地方,它能让你的页面轻快很多。

原生懒加载 loading="lazy" 有多香?我用了五分钟后,默默地删掉了以前的懒加载插件
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

版权声明:
本站资源有的来自互联网收集整理,本站纯免费分享提供学习使用,如果侵犯了您的合法权益,请发送邮件1506151422@qq.com联系,将会及时下架删除。
本站资源仅供研究、学习交流之用,免费开源项目不代表完全可商用,若商业用途请先咨询开发企业能否商用,否则产生的一切后果将由下载用户自行承担。
原创板块未经允许不得转载,否则将追究法律责任。

淘吗网 html 原生懒加载 loading=”lazy” 有多香?我用了五分钟后,默默地删掉了以前的懒加载插件 https://www.taomawang.com/web/html/2572.html

常见问题

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务