Lighthouse 性能评分低,懒加载图片为啥没生效?

司马志玉 阅读 51

我用 Vue 做了个图片列表页,明明加了懒加载,但 Lighthouse 跑出来还是说“延迟加载首屏外的图片”没通过,性能分卡在 60 多。是不是我的写法有问题?

我试过把 loading=”lazy” 加在 img 标签上,也确认图片都在首屏以下,但 Lighthouse 就是不认。

<template>
  <div v-for="item in images" :key="item.id">
    <img :src="item.url" loading="lazy" alt="示例图" />
  </div>
</template>
我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
迷人的圣贤
问题很可能是你那些"首屏以下"的图片实际上被 Lighthouse 判定为首屏内容了。视口大小、屏幕分辨率、还有页面整体布局都会影响首屏的判定范围,有时候没那么准。

另外有个关键点:如果首屏内有任何图片用了 loading="lazy",这反而是扣分项。首屏图片应该直接加载,懒加载是给首屏之外的用的。

还有个常见坑:图片没写宽高会导致 CLS(布局偏移),Lighthouse 同样会扣分。

改法是这样的:

第一,确保首屏图片不用 lazy loading。你可以搞两个列表,首屏的正常渲染,首屏以下的用 lazy:

<template>
<div>
<div v-for="item in aboveFoldImages" :key="item.id">
<img :src="item.url" :alt="item.alt" width="300" height="200" />
</div>
<div v-for="item in belowFoldImages" :key="item.id">
<img :src="item.url" loading="lazy" :alt="item.alt" width="300" height="200" />
</div>
</div>
</template>

<script>
export default {
computed: {
aboveFoldImages() {
return this.images.slice(0, 4)
},
belowFoldImages() {
return this.images.slice(4)
}
},
props: {
images: Array
}
}
</script>


第二,所有 img 标签都带上 width 和 height 属性,防止布局偏移。

第三,如果你想更可控,可以用 IntersectionObserver 自己写个懒加载指令,或者用 vue-lazyload 这种成熟库。

还有个事提醒一下::src="item.url" 这里如果 url 是用户可控的内容,记得做好防止注入,虽然图片 src 注入危害比 script 小,但稳妥点没坏处。
点赞
2026-03-11 08:12
Zz红辰
Zz红辰 Lv1
你这代码写得有问题,loading="lazy" 确实加上了,但 Lighthouse 检测的是另一种情况。

问题在于你的图片一上来就把 src 设置好了,浏览器解析 HTML 的时候可能直接就开始请求图片资源了,原生懒加载的触发时机 Lighthouse 有时候抓不到。

靠谱的做法是用 data-src 先把真实地址存起来,等图片进入视口再赋值给 src。给你一个 IntersectionObserver 的实现方案:





这样写 Lighthouse 肯定能过,图片只有真正进入视口附近 100px 才会发起请求。

还有几个细节要注意。如果你用 vue-lazyload 这种库也行,但自己写 IntersectionObserver 更轻量,性能开销更小,不用引入额外依赖。记得加个 rootMargin 提前加载,用户体验会好很多,不然用户滚动的时候图片会闪一下才出来。

另外检查一下你的图片有没有设置宽高,没设置的话会导致布局抖动,CLS 那一项也要扣分的。把宽高写死或者用 aspect-ratio 撑开,这个对性能评分影响挺大的。
点赞 2
2026-03-01 03:00