JS 实现图片懒加载的核心方法及 4 种优化技巧如下:
图片懒加载通过延迟加载非视口内的图片,减少初始资源请求,提升页面性能。以下是具体实现方案与优化策略:
一、核心实现方法1. data-src 属性 + 滚动监听- 原理:将真实图片地址存储在 data-src 中,初始 src 为占位图,滚动时检测图片是否进入视口,若进入则替换 src。
- 代码示例:<img src="placeholder.gif" data-src="real-image.jpg" alt="Image">const images = document.querySelectorAll('img[data-src]');function isInViewport(el) { const rect = el.getBoundingClientRect(); return ( rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.bottom >= 0 && rect.left <= (window.innerWidth || document.documentElement.clientWidth) && rect.right >= 0 );}function checkImages() { images.forEach(img => { if (isInViewport(img)) { img.src = img.dataset.src; img.removeAttribute('data-src'); } });}document.addEventListener('scroll', checkImages);checkImages(); // 初始检查
- 缺点:频繁触发滚动事件可能导致性能问题。
2. Intersection Observer API- 原理:浏览器原生 API,高效监听元素与视口的交叉状态,避免手动计算位置。
- 代码示例:const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.removeAttribute('data-src'); observer.unobserve(img); // 加载后停止观察 } });});document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));
- 优势:性能更优,推荐使用。
3. 结合 requestAnimationFrame 优化滚动监听- 原理:通过 requestAnimationFrame 限制滚动事件处理频率,减少重绘压力。
- 代码示例:let ticking = false;document.addEventListener('scroll', () => { if (!ticking) { window.requestAnimationFrame(() => { checkImages(); // 复用前文 checkImages 函数 ticking = false; }); ticking = true; }});
二、4 种优化技巧1. 预加载机制- 目标:在图片进入视口前提前加载,避免用户等待。
- 实现方式:
滚动监听 + offset:扩展视口检测范围。function isInViewport(el, offset = 100) { const rect = el.getBoundingClientRect(); return ( rect.top <= (window.innerHeight + offset) && rect.bottom >= -offset && rect.left <= (window.innerWidth + offset) && rect.right >= -offset );}
Intersection Observer + rootMargin:const observer = new IntersectionObserver((entries) => { /* ... */ }, { rootMargin: '100px 0px' // 上下各扩展 100px});
2. 选择合适的占位图- 关键因素:
大小:使用纯色、矢量图或极低质量图片(如 LQIP/SQIP),减少初始加载时间。
尺寸:占位图与真实图片尺寸一致,避免布局跳动。
风格:与页面整体设计协调,例如使用图片平均色或模糊处理。
- 常用方案:
纯色背景(如 background-color: #f0f0f0)。
矢量图标(如 SVG 简单图形)。
LQIP(低质量 JPEG 占位)。
SQIP(SVG 生成的低质量图片)。
3. 处理加载失败- 策略:
显示默认图片:通过 onerror 事件替换为备用图片。<img src="placeholder.gif" data-src="real-image.jpg" onerror="this.src='default.jpg'">
重试加载:延迟后重新尝试加载。img.onerror = function() { setTimeout(() => { img.src = img.dataset.src; }, 3000);};
错误提示:显示文字或图标提示用户。
4. 测试懒加载效果- 步骤:
打开浏览器开发者工具(F12),切换到 Network 面板。
勾选 Disable cache,清空记录。
滚动页面,观察图片请求是否按需触发(仅视口内图片加载)。
使用 Lighthouse 评估性能,优化加载时间与资源大小。
三、总结- 推荐方案:优先使用 Intersection Observer API,性能最佳且代码简洁。
- 兼容性处理:若需支持旧浏览器,可回退到滚动监听 + requestAnimationFrame。
- 综合优化:结合预加载、占位图与错误处理,全面提升用户体验。
图:懒加载核心逻辑流程图:Intersection Observer 代码结构通过以上方法,可显著减少页面初始加载时间,尤其适用于图片密集型网站(如电商、相册类页面)。