为什么我的页面TTI指标一直卡在8秒以上?优化后没明显改善

长孙晓曼 阅读 80

最近在优化一个电商详情页,Lighthouse评分里的TTI指标总是在8秒左右,用户反馈页面加载卡顿。页面用了Vue组件,图片都加了懒加载,还把CSS抽离成单独文件了,但测试结果还是差。折腾了半天,发现可能是某个组件的初始化代码拖慢了?

比如这个商品轮播图组件,代码逻辑看起来不复杂,但每次加载时控制台都会显示长时间任务:


<template>
  <div ref="carousel" class="carousel">
    <img 
      v-for="(src, index) in images" 
      :key="index" 
      :data-src="src" 
      @load="handleImageLoad" 
      class="lazy-img">
  </div>
</template>

<script>
export default {
  mounted() {
    // 手动实现Intersection Observer懒加载
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const img = entry.target;
          img.src = img.dataset.src;
          observer.unobserve(img);
        }
      });
    }, { rootMargin: '0px 0px 200px 0px' });

    this.$refs.carousel.querySelectorAll('.lazy-img').forEach(img => {
      observer.observe(img);
    });
  }
}
</script>

已经尝试过把图片尺寸压缩到200kb以内,合并JS打包,甚至把第三方统计脚本移到底部,但TTI还是没降到5秒以下。是不是懒加载实现有问题?或者有其他隐藏的性能瓶颈没发现?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
萌新.志敏
你这个问题我一看就知道坑在哪。TTI卡住大概率不是懒加载的问题,而是主线程被长任务阻塞了。你看看这几个点:

第一,图片没设宽高,加载完会触发重排,轮播图里一堆图片重排能把主线程卡死。给图片加固定的width和height,或者用aspect-ratio撑开容器。

第二,handleImageLoad里是不是写了什么计算逻辑?比如重新计算轮播图尺寸或者触发Vue响应式更新?这种在图片onload里搞事情最容易产生长任务。

第三,Vue组件初始化本身就有开销,如果轮播图组件不是首屏必须的,直接异步加载它:

const Carousel = () => import('./Carousel.vue')


第四,最容易被忽略的,你的第三方统计脚本是不是在head里?用deferasync加载,或者干脆等用户交互后再动态插入。

你先用Chrome DevTools的Performance面板跑一次,看看到底哪个函数执行时间最长,别瞎猜。八成是某个统计SDK或者广告脚本在搞鬼。
点赞 7
2026-03-02 11:23
东方春萍
你这懒加载没问题,但Vue的mounted钩子里干了太多事,Intersection Observer虽然高效,但每次初始化都会消耗时间。我一般直接用原生图片懒加载,浏览器自带的就挺好:

<img 
v-for="(src, index) in images"
:key="index"
:src="src"
loading="lazy"
class="lazy-img">


这样省掉一大坨JS开销,TTI能降不少。另外检查下Vuex或生命周期里有没有阻塞主线程的任务,console.time()帮你定位耗时代码。
点赞 16
2026-01-30 16:01