本文介绍一种轻量、可靠的方式:利用 IntersectionObserver 在 DOM 就绪后主动触发所有 loading="lazy" 图片的真实加载,避免手动移除属性的误区,并提供可直接运行的优化代码与关键注意事项。
本文介绍一种轻量、可靠的方式:利用 `intersectionobserver` 在 dom 就绪后主动触发所有 `loading="lazy"` 图片的真实加载,避免手动移除属性的误区,并提供可直接运行的优化代码与关键注意事项。
现代网页性能优化中,为 添加 loading="lazy" 是减少首屏资源请求数、加速 DOMContentLoaded 的常用手段。但若页面存在大量“非首屏但需尽快加载”的图片(如长页中部的内容图),单纯依赖浏览器原生懒加载可能造成用户滚动时明显延迟或空白。此时,一个更可控的策略是:在 DOM 构建完成(DOMContentLoaded)后,主动触发所有懒加载图片的加载,而非等待其进入视口——这既能保留首屏快速渲染的优势,又能提升后续内容的加载响应性。
以下是一个经过验证的完整实现方案:
新视窗企业管理系统是一款小巧、实用、利于后续开发的ASP程序。适合大中小型企业的网站建设。1、新闻管理 2、产品管理 3、订单管理 4、广告管理 5、下载管理 6、留言管理 8、单页栏目(如企业简介,资质荣誉)9、人才招聘等等。 新视窗企业管理系统 5.1 更新日志:1、修改产品列表的图片自动缩略,防止图片变形.2、修改后台添加产品分类时,排序ID不写入数据库的错误.3、修改首页企业简介的链接地址
document.addEventListener('DOMContentLoaded', () => {
// ✅ 正确选择:匹配所有 loading="lazy" 的 img 元素
const lazyImages = document.querySelectorAll('img[loading="lazy"]');
// ? 使用 IntersectionObserver 主动触发加载(即使已在视口外)
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
const img = entry.target;
// ⚠️ 关键:仅在未加载时才赋值 src,防止重复触发
if (!img.src || img.src === img.dataset.src) return;
// ✅ 安全赋值:优先使用 data-src,兼容传统懒加载写法
if (img.dataset.src) {
img.src = img.dataset.src;
} else if (img.srcset && img.dataset.srcset) {
img.srcset = img.dataset.srcset;
}
// ✅ 可选:移除 loading 属性以明确标识已激活(非必需,但语义清晰)
img.removeAttribute('loading');
// ✅ 停止观察该元素,避免重复回调
observer.unobserve(img);
});
},
{
// ? 设置 rootMargin 让观察提前触发(例如提前 200px 进入视口即加载)
rootMargin: '200px',
// threshold 设为 0 表示只要有一像素交叉即触发
threshold: 0
}
);
// ? 开始观察所有懒加载图片
lazyImages.forEach((img) => observer.observe(img));
});? 关键要点说明:
-
选择器必须准确:document.querySelectorAll("lazy") 错误地查找
标签;正确写法是 img[loading="lazy"],表示“所有 loading 属性值为 lazy 的 元素”。
- 无需手动 removeAttribute('loading') 来“启用”加载:浏览器原生懒加载机制在 loading="lazy" 存在时会自动延迟加载;而一旦你显式设置了 img.src(且非空),浏览器将立即发起请求——loading 属性本身不影响已赋值后的加载行为。移除它仅为语义标记,非技术必需。
- 务必校验 src 状态:避免重复赋值导致多次请求(尤其在 data-src 与 src 混用场景下),使用 if (!img.src || img.src === img.dataset.src) 是健壮实践。
- rootMargin 是性能杠杆:设置 '200px' 可让图片在用户滚动到其上方 200px 时就开始加载,显著提升感知流畅度,比“等完全进入视口再加载”更友好。
- 不推荐“全局移除 loading 属性”脚本:例如遍历所有 img 并 el.removeAttribute('loading'),这会破坏浏览器原生懒加载的底层调度逻辑,且无法保证资源按需加载顺序。
✅ 进阶建议:
若页面含无限滚动或时间线类组件(如社交 Feed),应结合 unobserve + removeChild 实现图片卸载(offscreen cleanup),防止内存持续增长。但对于常规静态长页,上述方案已足够高效、简洁且兼容性良好(支持 Chrome 76+、Firefox 75+、Safari 15.4+)。
最终效果:首页 145 个请求中约 87 张图片在 DOMContentLoaded 后被主动、批量、无阻塞地触发加载,首屏时间不变,整体内容就绪时间显著缩短。









