HTML loading=lazy 加 decoding=async 实战,图片加载终于不被卡脖子了

2026-08-30 0 378

以前提到图片懒加载,第一反应就是引入 intersection observer 或者 jquery.lazyload。现在呢?老老实实写两个 HTML 属性就完事了——loading="lazy"decoding="async"。这俩属性说起来简单,但很多人都只是听说过,没有真正理解怎么用。今天从原理到实战,把图片加载的最后一公里安排得明明白白。

从一张图片说起

浏览器加载 HTML 时,遇到 <img> 后,会先下载图片,然后解码成位图,最后再绘制到页面上。这个过程在大量图片的页面里,会严重影响首屏速度。尤其是移动端,网络又慢,图片一多就白屏。

loading="lazy" 就是告诉浏览器:这张图片先别急着下载,等它快要进入视口时再开始加载。简单说,它就是浏览器内置的懒加载能力,完全不用写 JS。

decoding="async" 则是让浏览器在解码图片时不要阻塞其余 HTML 的渲染。默认解码方式可能是同步的,这意味着浏览器可能在解码完一张图片前,不继续渲染下面的内容。用了 async 后,解码过程放到后台,页面先展示文字和结构,图片什么时候解码完了什么时候出现。

基础用法就是加两个属性

<img src="big-photo.jpg" alt="风景" loading="lazy" decoding="async">
    

就这一句话。没有数据属性,没有回调函数。浏览器自己判断元素位置,自己调度网络请求。而且图片未进入视口时不会加载,进入视口前大约 300px 就开始预加载,体验很丝滑。

实战:改造一个多图页面

我搞了一个简单的画廊页面,里面放了 20 张 800×600 的测试图。改造前,一打开页面就同时发送 20 个请求,加载完页面得好几秒。改造后,甚至网络面板只显示首屏附近的几个请求。

第一步:先把所有图片加上懒加载和解码异步。下面是改造后的一个典型模板:

<div class="gallery">
  <img src="photo1.jpg" alt="作品 1" loading="lazy" decoding="async" width="800" height="600">
  <img src="photo2.jpg" alt="作品 2" loading="lazy" decoding="async" width="800" height="600">
  <img src="photo3.jpg" alt="作品 3" loading="lazy" decoding="async" width="800" height="600">
  <!-- 后面还有 17 张 -->
</div>
    

注意我特意加了 widthheight。因为如果不给图片占位尺寸,浏览器不知道图片的宽高比,页面会在图片加载后发生布局偏移(CLS),影响性能评分。而咱们做的是性能优化,CLS 可不能糟糕。

第二步:对于首屏第一张图(或关键图),不要加 lazy,正常加载,例如:

<img src="hero.jpg" alt="头图" width="1920" height="800" fetchpriority="high">
    

第一张轮播图或者 Logo,最好用 fetchpriority="high" 提示浏览器优先加载,而 lazy 会让它延迟,看不到首屏效果。比例子中的 hero 图就不该加 lazy。

怎么验证懒加载生效了?

打开 Chrome 开发者工具,切到 Network 面板,筛选 Img 资源,然后重新加载页面。你会看到只有视口附近的图片被加载了。当你滚动页面,新的图片才不断出现。如果滚动到底部,你还能看到有些图片根本没有请求,这就是懒加载起效了。

再切到 Performance 面板,观察“解码图片”的时间,你会发现如果用了 decoding="async",Decode Image 任务不会阻塞主线程渲染,交互响应更快。

一个看似简单但很重要的细节:动态图片怎么办?

懒加载并不是神奇的魔法,如果你在页面加载后通过 JS 动态插入一张图片,浏览器不会自动应用加载行为,即使它带有 loading="lazy" 属性?实际上如果图片本来就带这个属性,它是有效的。比如你用 innerHTML 插入一段包含 <img loading="lazy"> 的 HTML,浏览器会正确识别。但如果你只是给一个已有的 img 对象赋值属性,那就要看时机。所以最好的做法是在插入 HTML 时就带上属性。

还有人说:loading="lazy" 对 iframe 也有效?没错,iframe 也支持,建议给那些不是首屏的视频嵌入或广告 iframe 加上。

解码 async 和懒加载是否总有冲突?

没有冲突。它们是两个不同维度的优化。懒加载控制“什么时候开始下载图片”,decoding 控制“下载完成后,如何解码”。你可以单独使用一个,也可以组合使用。事实上,Google 的 PageSpeed Insights 经常建议同时添加这两个属性。

但是要注意:decoding="async" 对于很小的图片(比如头像图标)不会带来明显提升,而且还可能让图片延迟出现(因为异步解码会和其他任务排队)。如果你使用 CSS 设计关键的背景图,那用不上这个属性,只有 <img> 元素才有。

还需要考虑 JS 回退吗?

如果你需要支持非常老的浏览器(比如 IE),那真得用 polyfill。但现在是 2025 年,loading="lazy" 已经得到所有现代浏览器的支持(包括 Safari 15.4+)。至于 decoding="async",Safari 也在 15.4 后支持了。所以直截了当地用吧,不要为老古董浪费时间。

一个完整的示例页面

下面是一个包含不同图片的完整页面,你可以直接复制保存为 HTML 文件测试效果。我完全没有写任何样式,只是为了演示属性。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <title>原生懒加载演示</title>
</head>
<body>
    <h1>向下滚动查看懒加载效果</h1>
    <img src="https://picsum.photos/id/10/800/600" alt="示例图1" loading="lazy" decoding="async" width="800" height="600">
    <p>这是一段描述文字,它应该立刻显示。</p>
    <img src="https://picsum.photos/id/20/800/600" alt="示例图2" loading="lazy" decoding="async" width="800" height="600">
    <p>中间内容,比较长。</p>
    <img src="https://picsum.photos/id/30/800/600" alt="示例图3" loading="lazy" decoding="async" width="800" height="600">
    <p>继续滚动……</p>
    <img src="https://picsum.photos/id/40/800/600" alt="示例图4" loading="lazy" decoding="async" width="800" height="600">
    <p>下面还有</p>
    <img src="https://picsum.photos/id/50/800/600" alt="示例图5" loading="lazy" decoding="async" width="800" height="600">
</body>
</html>
    

你最好自己找一些大图片替换链接,这样效果更明显。加载这个页面时,注意控制台 Network 面板,你会发现首屏其实只加载了第一张图(甚至第一张都不加载,如果它不在视口内)。而文字和后面的内容会立即显示。这就是原生懒加载的价值所在。

再深入一点:CSS 背景图是否也有类似属性?

很遗憾,CSS 背景图没有原生的 loading="lazy" 属性。如果你有背景图需求,可以改用 <img> 元素作为背景,或者使用 JS。但今天的话题是纯 HTML,所以就不展开了。

总结与最佳实践

  • 首屏关键图片(Logo、banner)不要用 loading="lazy",给它们加上 fetchpriority="high" 更好。
  • 非首屏图片、小型轮播图以外的所有 <img> 都加上 loading="lazy"decoding="async"
  • 记得给每张图设定 widthheight,避免累加 CLS。
  • 如果是动态插入的图片,确保字符串中包含这两个属性。如果使用 JS 的 Image() 对象,无法直接设置,但这种方式不常用,建议还是用 HTML 字符串。
  • 别忘给视频或 iframe 也加上 loading="lazy"

现在很多前端打包工具会自动给 <img> 加上这些属性,比如 Next.js 的 Image 组件会自动处理。如果你在写原生 HTML,或者后端渲染模板,一定要手写上去。

最后说一句:以前我们写的懒加载库可能有各种自定义的占位图、错误处理,但原生方案简单粗暴,性能却更好,因为浏览器调度网络比 JS 更智能。与其纠结要不要用某个库,不如直接跑起来试试。

以后做页面,看到图片就条件反射地加这两属性,已经长在肌肉里了。

HTML loading=lazy 加 decoding=async 实战,图片加载终于不被卡脖子了
收藏 (0) 打赏

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

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

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

淘吗网 html HTML loading=lazy 加 decoding=async 实战,图片加载终于不被卡脖子了 https://www.taomawang.com/web/html/2668.html

下一篇:

已经没有下一篇了!

常见问题

相关文章

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

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