loading="lazy"仅控制加载时机,不决定加载哪张图;必须配合srcset+sizes才能按设备选合适分辨率图片,否则移动端仍下载大图;首屏图须用preload+loading="eager"确保立即加载,避免白屏或lcp崩溃。

单独加 loading="lazy" 不能解决移动端下载大图的问题,必须和 srcset + sizes 配合使用;而首屏关键图如果只靠懒加载,大概率会白屏或 LCP 崩溃——得用 preload 提前抓取。
为什么 loading="lazy" 和 srcset/sizes 必须一起写
浏览器对 loading="lazy" 的处理只决定“什么时候开始选图”,不决定“选哪张”。如果只写 <img src="big.jpg" loading="lazy">,移动端仍会下载桌面尺寸的 2MB 图片,只是延迟了 2 秒——流量没省,LCP 反而更差。
-
srcset列出多个宽度候选,比如"cat-400w.webp 400w, cat-800w.webp 800w, cat-1200w.webp 1200w" -
sizes必须成对出现,告诉浏览器“这张图在不同断点下实际占多宽”,例如"(max-width: 480px) 100vw, (max-width: 1024px) 50vw, 300px";漏掉max-width: 480px会导致 320px 屏幕回退到100vw -
src只作降级兜底,必须是小尺寸图(如cat-400w.webp),不能留空或指向大图 - 所有尺寸单位统一用
w(源图固有宽度),别混用x或px
首屏图必须用 preload + loading="eager"
Chrome 默认对没声明 loading 的图按 eager 处理,但 Safari(尤其 iOS 16.3 及更早)可能把没声明的图也懒掉,导致 Banner 白屏。
- 首屏 Hero、Logo、头像等必须显式写
loading="eager" - 同时在
加<link rel="preload" as="image" href="hero.webp">,且href必须和<img>的src完全一致 - 禁用
decoding="async"(首屏图解码不能异步,否则 LCP 可能卡顿) - 宽高必须用 HTML 属性写死,比如
width="1200" height="600",避免 SSR 渲染时无占位引发 CLS
loading="lazy" 生效的硬性前提
这个属性不是写了就生效。浏览器只对「初始 HTML 就存在、不在首屏、有明确 width 和 height、父容器没 transform/overflow: hidden 干扰」的 <img> 生效;其他情况静默退化为 eager。
- 缺少
width/height属性(设成100%或vw也不行),Safari 15.4+ 直接拒懒加载 - 把
loading="lazy"错写在<source></source>上——该属性只对最外层<img>有效 - 图片由 Vue/React 动态渲染(如
v-for或map()),不属于初始 HTML,Chrome 可能立即加载,Firefox 可能延迟白屏 - 父容器用了
transform: translateZ(0)或contain: layout,干扰 Intersection Observer 检测逻辑
preload 和 prefetch 别混用
preload 是告诉浏览器“这个资源马上就要用,现在就去下”,prefetch 是“可能以后会用,空闲时再下”。混淆会导致关键资源被延迟或带宽被浪费。
-
preload只用于当前导航中明确需要的资源:比如<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>(注意必须加as和crossorigin) -
prefetch适合下一页可能用到的 JS 或图片,比如用户进入详情页前预取comments.js - Chrome DevTools 的 Network 面板里,
preload请求会标为Priority: high,prefetch则是low——这是验证是否写对的最快方式
真正容易被忽略的是 sizes 和 CSS 布局的同步:如果 CSS 里把图片容器设为 max-width: 50vw,但 sizes 还写着 "100vw",浏览器就会选错图。每次改布局,sizes 得跟着动。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











