layoutshift 是 performance api 中用于诊断 cls 的性能条目类型,需用 performanceobserver 监听并启用 includesources: true 才能定位违规元素,修复须从 html/css 预留空间、字体加载策略及动态内容占位等层面入手。

LayoutShift 不是 HTML5 的一个标签或属性,也不是可以直接“捕捉”的 HTML 功能。它是浏览器 Performance API 中的一种性能条目类型(PerformanceEntry 子类),需通过 PerformanceObserver 主动监听,用来识别并定位导致 CLS(累积布局偏移)的具体元素和时机——但本身不修复问题,只提供诊断依据。
要真正修复累积布局偏移,必须回到 HTML 和 CSS 层面干预诱因。下面分三步讲清楚:怎么捕获、怎么看懂、怎么改。
用 PerformanceObserver 监听 LayoutShift 条目
只有现代浏览器支持(Chrome 84+、Edge 84+,Firefox 尚未支持)。先确认可用性,再注册观察者:if ('layoutShift' in PerformanceObserver.supportedEntryTypes) {
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.value > 0.002) { // 忽略微小抖动(<p>⚠️ 注意:默认 <code>entry.sources</code> 为空。要看到具体元素,必须启用 <code>includeSources: true</code>(仅 Chrome 支持):</p><pre class="brush:js;toolbar:false;">observer.observe({
entryTypes: ['layoutShift'],
includeSources: true // ✅ 必加,否则 sources 是空数组
});从 sources 中定位“不稳定元素”
每个 `LayoutShift` 条目里的 `sources` 是一个数组,每项含: - `node`:发生位移的 DOM 元素(可能为 `null`,尤其跨 iframe 或匿名节点) - `previousRect` / `currentRect`:位移前后的布局框(可算出移动距离和影响范围)常见可定位的违规模式:
-
<img>或<iframe></iframe>没设width/height→node指向该标签,currentRect.height明显大于previousRect.height - 字体加载后文本重排 →
node往往是包含文本的<p></p>或<h1></h1>,currentRect.width/height变化明显 - 广告容器动态插入 →
node是广告 wrapper,previousRect面积为 0(即原无占位)
✅ 实用技巧:在 DevTools Console 中打印 entry.sources[0]?.node?.outerHTML,快速定位到 HTML 片段。
针对性修复 HTML/CSS 诱因
CLS 数值只是结果,修复靠约束渲染预期。常见场景与写法:-
图片/视频未预留空间
❌ 错误:
<img src="hero.jpg">✅ 正确:显式宽高 + `loading="lazy"` + `decoding="async"`<img src="hero.jpg" style="max-width:90%" style="max-width:90%" alt="">或更现代方案(兼容性好时):aspect-ratio: 16/9;+ `object-fit` -
字体导致文本跳动
❌ 错误:直接引用 Web Font 且无 fallback 占位 ✅ 正确:
@font-face { font-display: swap; size-adjust: 100%; }并确保 fallback 字体(如 `font-family: "Inter", system-ui;`)字宽相近 -
动态内容(广告、评论、嵌入)无高度预留
❌ 错误:JS 插入 `
` 后再请求广告 ✅ 正确:<div id="ad-slot" style="min-height: 250px; background: #f5f5f5;"></div>或用 `contain: layout` 隔离影响:style="contain: layout;" -
使用
position: relative做微调却引发缩放错位❌ 错误:`.menu { position: relative; top: -2px; }` ✅ 正确:改用 `transform: translateY(-2px)`(不触发重排) 或包裹一层 `position: relative` 容器,内部用 `absolute` 定位(基准更稳)
不复杂但容易忽略
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











