原生 loading="lazy" 是最简单可靠的懒加载方案,但需处理浏览器兼容性与 fallback;intersectionobserver 是主流手动实现方式,比 scroll 监听更稳定高效;须配合 css 占位防抖动,并妥善处理加载失败。

原生 loading="lazy" 是最简单可靠的方案,但需注意浏览器兼容性和 fallback 处理。
用 loading="lazy" 属性直接启用原生懒加载
现代浏览器(Chrome 76+、Edge 79+、Firefox 75+、Safari 15.4+)支持 img 标签的 loading 属性:
@@##@@
它会自动在图片进入视口前延迟加载。无需 JS,不触发重排,性能开销最低。
- 仅对
<img src="photo.jpg" loading="lazy" alt="描述">和<iframe></iframe>生效,background-image不支持 - 若
src为空或无效,部分浏览器仍会发出 404 请求,建议确保src合法 - 服务端渲染(SSR)时该属性会被保留,但首次 HTML 加载时不会提前触发加载
当需要兼容老浏览器或自定义逻辑时,用 IntersectionObserver
这是目前最主流的手动实现方式,比监听 scroll 更轻量、更稳定:
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
对应 HTML 写法:
@@##@@
- 务必设置
width和height(或 CSS 尺寸),避免懒加载触发前页面抖动 -
IntersectionObserver在 Safari 12.1+ 才完整支持,iOS 12.0 及更早需降级处理 - 不要在
entry.isIntersecting === true前就替换src,否则可能重复加载
慎用 scroll 事件监听实现懒加载
虽然写起来直观,但极易引发性能问题:
window.addEventListener('scroll', () => {
// 每次滚动都遍历所有 img → 卡顿
});
- 没有节流或防抖时,滚动过程可能每秒触发数十次,严重拖慢主线程
- 无法感知元素是否真正可见(比如被
overflow: hidden父容器裁剪) - 移动端 touchmove 频率更高,问题更明显;已基本被
IntersectionObserver取代
图片占位与加载失败处理不能省略
懒加载让图片“晚出现”,但用户不该看到空白或错位:
- 用
aspect-ratio或固定宽高 +object-fit保持布局稳定 - 加载失败时显示 fallback 文字或图标:
img的onerror事件可兜底 - 避免把
data-src当成唯一来源——服务端若未下发该属性,前端 JS 就会失效
原生 loading="lazy" 看似一劳永逸,但它不提供加载中状态、错误重试或自定义阈值;真正要兼顾体验和兼容性,往往得组合使用属性 + 观察器 + CSS 占位。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











