为什么我的LCP评分总是卡在2.5秒以上?优化后还是没达标
最近在优化网站LCP指标,把关键资源压缩到200KB以内了,也用了标签,但实测LCP还是2.6秒左右。我用Lighthouse测试发现,那个大图的传输时间显示1.8秒,为啥总时间这么高?
尝试过把图片转WebP格式,服务器配置了Accept-Encoding,但看Network面板,这张图的Content-Encoding还是gzip。是不是需要同时启用Brotli?还有个问题,用IntersectionObserver做懒加载时,预加载提示怎么写才能让浏览器优先渲染关键图片?
现在代码是这样写的:<img src="placeholder.jpg" data-src="large.jpg" class="lazyload">,但LCP还是检测到大图在可视区加载。是不是应该用preload标签?比如这样:
<link rel="preload" href="large.jpg" rel="external nofollow" as="image" onload="this.rel='preload'">
但加上后首屏反而卡得更严重了,有没有更好的实现方式?
首先Content-Encoding是gzip没问题,WebP本身已经是压缩格式,关键是传输体积和请求时机。你看到Network里大图耗时1.8秒,说明它是在页面解析到
解决方案分两步:
第一,必须用preload明确告诉浏览器:这张图是关键资源,立刻拉!但你写的那个onload="this.rel='preload'"是错的,语法乱写会导致资源重复加载甚至阻塞。正确写法:
注意加上fetchpriority="high",这是Chrome 103+的新属性,能强制提升请求优先级。别再用lazyload类库去处理LCP元素,懒加载和LCP是对立的。
第二,确认服务器开启Brotli。虽然图片一般不走Brotli(因为自身已压缩),但CSS/JS走Brotli能省下几百毫秒,间接给图片腾出带宽。Nginx加这句就行:
最后检查下large.jpg是不是真的在首屏可见区域。有时候布局抖动导致图片延迟进入视口,也会拖累LCP。可以加个内联的宽高防抖动:
代码放这了,照着改一遍,LCP能压到2秒内。别折腾IntersectionObserver预加载提示了,那种方案浏览器根本不认作关键资源。