Q4 · 性能指标

如何用代码获取 CLS?指标分数段?怎么提升?

CLSCore Web Vitals布局稳定性

⚡ 速记答案(30 秒)

  • 获取:PerformanceObserver 监听 layout-shift,累加非 hadRecentInput 的分数
  • 分数段:好 < 0.1;一般 0.1–0.25;差 > 0.25
  • 所有图片、视频、广告位预留宽高/容器
  • 避免在已有内容前插入新 DOM(特别是同步接口返回后)
  • 动画用 transform/opacity,不要频繁更改 top/left/height 等引发布局

📖 详细讲解

CLS 定义


Cumulative Layout Shift:页面生命周期内所有意外布局偏移的累积分数。


计算公式


CLS = 影响比例 × 移动比例

影响比例:不稳定元素影响的可视区域比例

移动比例:不稳定元素移动的距离占视口的比例


常见原因


1. 图片/视频没有尺寸属性

2. 动态插入内容

3. Web 字体加载导致文字重排

4. 动态注入广告


优化策略


1. 预留空间

• 图片使用 width/height 或 aspect-ratio

• 广告位预留固定高度


2. 避免动态插入

• 新内容插入到现有内容下方

• 使用 CSS transform 动画

💻 代码示例

获取 CLS 指标
let clsValue = 0;
let clsEntries: PerformanceEntry[] = [];

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries() as any[]) {
    // 忽略用户输入导致的布局偏移
    if (!entry.hadRecentInput) {
      clsValue += entry.value;
      clsEntries.push(entry);
    }
  }
  console.log('当前 CLS:', clsValue);
});

observer.observe({ type: 'layout-shift', buffered: true });
预防 CLS 的 CSS
/* 图片预留宽高比 */
img {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
}

/* 广告位预留高度 */
.ad-slot {
  min-height: 250px;
}

/* 使用 transform 而不是位置属性 */
.animated-element {
  transform: translateY(10px); /* ✅ 不会触发 CLS */
  /* top: 10px; ❌ 会触发 CLS */
}
💡
面试技巧:回答性能问题时,先说指标和标准,再讲优化手段,最后结合实际项目经验。