必须为设置width和height属性以防止布局抖动,配合data-src懒加载、intersectionobserver监听及onerror防御式回退,形成完整占位链路。

用 width 和 height 属性锁住图片尺寸,避免布局抖动
没设宽高的 <img> 标签在图片加载前是“无尺寸”的,浏览器无法预留空间,加载后突然撑开会导致下方内容跳动(layout shift)。这是最常被忽略、影响最大的问题。
解决方式很简单:直接在 HTML 中写死 width 和 height 属性(不是 CSS),哪怕只是近似值。例如:
@@##@@
- 现代浏览器会据此计算宽高比,即使图片未加载也能维持容器比例
- 如果响应式需求强,可用
aspect-ratio: 3/2替代,但注意 Safari 15.4+ 才稳定支持 - 千万别只靠
max-width: 100%——它不提供初始占位能力
用 data-src + 占位图实现懒加载占位,而不是依赖 loading="lazy"
loading="lazy" 只控制请求时机,不提供任何视觉占位。它一启用,图片未加载时就是透明塌陷区,FOUC 和白屏不可避免。
真要占位,得自己管加载流程:
- 把真实地址存在
data-src(或data-srcset),src放一个极小的 base64 占位图:src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" - 必须同步处理
srcset和sizes:存为data-srcset和data-sizes,JS 加载时一并赋值,否则高 DPR 设备会加载错尺寸 - Safari 对空
srcset敏感——赋值前确保它是空字符串"",别留srcset=""
用 IntersectionObserver 触发加载,别绑 scroll 事件
滚动监听容易卡顿、漏触发、重复执行,尤其在快速滑动时,图片刚进视口就又滚出去,导致反复加载/取消。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
IntersectionObserver 是目前唯一靠谱的选择:
- 创建一次观察器,复用给所有图片:
const observer = new IntersectionObserver(...) - 用
rootMargin: '50px'提前加载,防止滚动过快时出现空白 - 进入视口后立即调用
observer.unobserve(img),否则持续监听浪费资源 - 必须检查
img.complete:缓存图片可能已加载完成,跳过load事件,需直接标记为 loaded
加载失败时 fallback 占位不能只靠 onerror 内联写法
onerror="this.src='fallback.jpg'" 在多数场景下根本不会生效——因为 fallback 路径本身又 404,触发第二次错误,而浏览器会静默阻止二次 onerror 回调。
最小可行方案必须带防御:
- 内联写法唯一可靠形式:
onerror="this.onerror=null;this.src='/assets/placeholder.svg'" - 占位图优先选
.svg:体积小、无渲染失败风险、天然透明背景 -
alt文字不能省——它是无障碍基础,也是视觉降级时最后的兜底 - 更健壮的做法是放弃
onerror,改用 CSS:has()检测缺失src(Chrome 105+/Safari 15.4+),再配合 JS 补充 404 场景
真正难的不是写几行代码,而是把宽高、srcset 同步、IntersectionObserver 生命周期、fallback 链路这四件事串成一条不掉链子的流水线。漏掉任意一环,占位就退化成“假装有占位”。

前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










