loading="lazy"仅对初始html中存在、不在首屏、有明确宽高且父容器无干扰样式的生效;其余情况退化为eager甚至拖慢首屏。

直接加 loading="lazy" 不等于图片真会懒加载——它只对「初始 HTML 就存在、不在首屏、有明确宽高、父容器没干扰样式」的 <img> 生效;其他情况大概率退化为 eager,甚至拖慢首屏。
为什么 loading="lazy" 写了但图片还是全量加载
浏览器只在首次 layout 后批量检查可视性,以下任一条件不满足,就会退化为 eager 加载:
-
<img>缺少width和height属性(或设为%/vw),导致无法推断尺寸 - 图片被包裹在
overflow: hidden、transform、contain: layout或will-change: transform的父容器中 - 图片是 JS 动态插入的(如 Vue
v-for、Reactmap()渲染),不属于初始 HTML - 用了
<picture></picture>但把loading="lazy"错写在<source></source>上(该属性只对<img>有效) - 用
position: absolute; top: -9999px占位,浏览器认为它“已渲染但不可见”,不触发懒加载
首屏关键图必须显式声明 loading="eager"
别依赖默认行为——Chrome 默认 eager,但 Safari(尤其 iOS 16.3 及更早)可能把没声明的图也懒掉,导致 banner 白屏。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 首屏 Hero 图、Logo、核心按钮图标,必须同时满足:
loading="eager"+<link rel="preload" as="image" href="hero.webp"> -
<link rel="preload">的href必须和<img>的src完全一致,否则浏览器当两个资源处理,重复下载 - 禁止给
loading="lazy"的图再preload——预加载和懒加载逻辑冲突,反而增加竞争
data-src + IntersectionObserver 自定义懒加载怎么不翻车
需要 fallback、提前加载、LQIP 占位或兼容老浏览器时才上手写,但容易卡主线程或触发重排:
- 初始
<img src="placeholder.svg">必须设width/height,防布局抖动 - 真实地址存
data-src,回调里只做两件事:img.src = img.dataset.src+observer.unobserve(img) - 监听前先过滤已在视口内的元素:
Array.from(images).filter(img => img.getBoundingClientRect().top ,避免刚进页面就批量触发 - 别在回调里调 AJAX、改 class、触发动画或操作其他 DOM——这些都会打断渲染帧
srcset 和 sizes 配错会让懒加载白忙活
只写 srcset 不配 sizes,浏览器根本不知道图片占多宽,只能瞎猜,移动端常拉取 2000w 桌面图。
-
sizes值必须反映**实际占位宽度**,不是视口宽度。例如:sizes="(max-width: 600px) 100vw, 800px" - 响应式图片建议用
<picture></picture>包一层:<source type="image/webp" srcset="..."></source>在前,<img src="fallback.jpg">在后 - 所有非首屏
<img>必须加loading="lazy";首屏图片则去掉该属性,确保立即加载
真正难处理的是 fallback 后要不要再 fallback:比如默认图也挂了,是否要 fallback 到 base64、是否要记录失败次数、是否要上报监控。这些边界情况往往被忽略,但线上一出问题就是静默白屏。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










