图片懒加载避免布局抖动需设宽高属性或aspect-ratio,用css骨架屏占位,intersectionobserver合理配置rootmargin,onerror优雅降级。

图片懒加载时如何避免布局抖动
不设宽高或仅用 width/height 属性值,浏览器无法预留空间,图片加载后会把下方内容往下顶——这是最常见抖动原因。必须让占位区域在 JS 加载前就占据准确尺寸。
- 推荐在
<img>上直接写死width和height属性(非 CSS),例如<img style="max-width:90%" style="max-width:90%">,现代浏览器会据此计算 aspect ratio,即使 CSS 覆盖也能保布局稳定 - 若尺寸动态,用
aspect-ratio: 3 / 2(CSS)+width: 100%替代,但注意 Safari 15.4+ 才完全支持 - 禁用
object-fit: cover等缩放属性干扰原始尺寸推算,骨架屏阶段先用纯色背景占位更可控
用 CSS 实现轻量级骨架屏占位
不用 JS 渲染骨架 DOM,纯 CSS 动画模拟“加载中”状态,性能好、兼容强。关键在于用 ::before 或 ::after 叠加渐变遮罩 + 骨架形状。
- 给图片容器设固定宽高和相对定位,例如
<div class="img-placeholder" style="width: 300px; height: 200px; position: relative;"> <li>用伪元素画骨架:设置 <code>background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%)+background-size: 200% 100%+animation: loading 2s infinite - 图片加载完成时,通过
img.onload或IntersectionObserver移除容器上的loading类,停止动画并显示真实图片 - 设
rootMargin: '100px'让图片在进入视口前 100px 就开始加载,兼顾性能与体验 - 对首屏图片(
loading="eager")跳过观察,避免重复请求;对长列表中的图片,可配合节流防高频回调 - 注意 Safari 对
IntersectionObserver的兼容性:iOS 12.2+ 支持,旧版需降级为scroll+getBoundingClientRect() - 若页面有
transform容器(如轮播图 wrapper),需将root显式设为该容器,否则监听失效 - 在
img.onerror中移除loading类,并添加error类,用 CSS 显示 fallback 文字或图标,例如.error::after { content: "⚠"; color: #666; } - 避免用
img.src = fallbackSrc二次赋值——可能触发新请求失败循环;优先用已知可用的本地占位图(如 data URL) - 服务端若支持,可通过
<picture></picture>+<source type="image/webp"></source>提供多格式兜底,但注意onerror不会冒泡到<picture></picture>,仍要绑定在每个<img>上
IntersectionObserver 触发懒加载的边界条件
不是所有滚动场景都适合默认阈值。过早加载浪费带宽,过晚加载造成白屏或闪动。
加载失败时如何优雅回退
网络中断、路径错误、CORS 限制都会导致 img.onerror 触发。此时骨架屏不能残留,用户需要明确反馈。
width/height 属性缺失与 IntersectionObserver 的 root 上下文错配——这两点几乎覆盖了 80% 的懒加载布局异常和加载静默问题。











