采用图片延迟加载方案后仍遭PageSpeed提示,求有效懒加载方案
你的方案是否有效?以及更优的懒加载方案
首先直接给结论:你当前使用的方案不属于PageSpeed所要求的「屏幕外图片懒加载」,这也是检测工具仍给出提示的原因。
为什么现有方案不满足要求?
你的方案是在window.onload触发时,一次性把所有图片的data-src替换为src——这意味着不管图片在不在当前视口(哪怕是屏幕外的底部图片),都会在页面加载完成后立刻被加载。而PageSpeed要求的懒加载,核心是仅加载当前用户可见区域的图片,屏幕外的图片等用户滚动到它们的位置时再加载,这样能显著减少初始加载的资源体积,降低交互时间(TTI)。
更优的解决方案推荐
1. 原生HTML loading="lazy" 属性(首选)
这是最简单、性能最好的方案,直接利用浏览器原生支持的懒加载能力,不需要额外编写JS代码:
<img src="image1.jpg" loading="lazy" alt="image 1">
- 优势:浏览器原生实现,性能远优于自定义JS,无需维护额外代码,主流浏览器(Chrome、Firefox、Edge、Safari 15.4+)都已支持
- 注意:首屏可见的图片不要加这个属性,否则会延迟首屏内容加载,影响LCP(最大内容绘制)指标
2. 基于Intersection Observer API的自定义JS方案(适合兼容旧浏览器或自定义需求)
如果你需要兼容更老的浏览器,或者需要自定义懒加载的触发时机(比如图片进入视口前100px就开始加载),可以使用Intersection Observer API——这是专门为检测元素是否进入视口设计的API,性能比传统的scroll事件监听好很多(不会频繁触发回调):
document.addEventListener('DOMContentLoaded', function() { // 获取所有带data-src的懒加载图片 const lazyImages = document.querySelectorAll('img[data-src]'); // 创建观察者实例 const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { // 当图片进入视口时 if (entry.isIntersecting) { const img = entry.target; // 替换src img.src = img.dataset.src; // 移除data-src属性 img.removeAttribute('data-src'); // 停止观察该图片 observer.unobserve(img); } }); }, { // 可选:设置提前加载的阈值,比如图片距离视口100px时就开始加载 rootMargin: '100px 0px' }); // 对每个懒加载图片启动观察 lazyImages.forEach(img => imageObserver.observe(img)); });
- 优势:性能优异,支持自定义加载时机,兼容性可以通过polyfill解决旧浏览器的问题
- 配合你的base64占位符使用,可以避免页面布局偏移(CLS)
3. 关键注意事项
- 区分首屏和非首屏图片:首屏可见的图片直接用
src加载,不要懒加载,保证首屏内容快速显示 - 保留占位布局:可以用CSS给图片设置固定的宽高,或者继续使用你的base64占位符,避免图片加载时页面布局跳动,影响CLS指标
内容的提问来源于stack exchange,提问作者Hookstark
相关产品推荐
相关产品推荐

