现代浏览器原生支持 loading="lazy",比 JS 插件更轻量可靠;它仅适用于 img 和 iframe,需配合 src 使用,不兼容 CSS 背景图等场景,老浏览器可降级用 IntersectionObserver。

直接用 loading="lazy" 就够了,不需要 JS 插件。
为什么现在不推荐手写 JS 懒加载插件
现代浏览器(Chrome 76+、Firefox 75+、Edge 79+、Safari 15.4+)原生支持 loading="lazy",它由浏览器内核控制,比 JS 实现更轻量、更可靠、更省电——JS 插件反而可能因执行时机、滚动监听抖动、IntersectionObserver 兼容性等问题导致图片漏载或重复加载。
- JS 插件需手动引入、初始化,容易忘记加
data-src或漏调load() - 在低性能设备上,JS 滚动监听会抢占主线程,造成卡顿
- 部分插件对
srcset、picture元素支持不全,响应式图片失效 - 服务端渲染(SSR)场景下,JS 插件常因 DOM 未就绪而报错
Cannot read property 'querySelectorAll' of null
loading="lazy" 的正确写法和限制
它只对 和 生效,且仅在非首屏、垂直方向滚动时触发。必须配合 src 使用(不能只写 data-src),否则图片不会显示。
- ✅ 正确:

- ❌ 错误:
(浏览器忽略data-src,不加载) - ⚠️ 注意:
loading="lazy"对 CSS 背景图、object、video poster无效 - ⚠️ 注意:若图片在视口内(比如首屏轮播图),
loading="lazy"会被自动忽略,仍立即加载
需要兼容老浏览器?用降级方案,不是换插件
如果必须支持 IE 或旧版 Android WebView,优先用 IntersectionObserver + 原生 src 回填,而不是引入 jQuery LazyLoad 这类重型插件。
立即学习“前端免费学习笔记(深入)”;
if ('IntersectionObserver' in window) {
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));
}
- 只监听有
data-src的,避免污染首屏 - 加载后立即
unobserve,防止重复触发 - 不依赖第三方库,压缩后不到 1KB
- IE 需额外引入
intersection-observerpolyfill(仅 5KB)
真正难的不是“怎么让图片懒加载”,而是判断哪些图该懒、哪些不该懒——比如商品列表页第二屏的图可以懒,但详情页顶部主图必须立即加载。这个决策藏在业务逻辑里,JS 插件解决不了。











