cumulative layout shift 怎么查怎么修:四步把乱跳的内容按住
cumulative layout shift 是衡量视觉稳定性的那个 Core Web Vital,第 75 百分位要不高于 0.1。这一章给你四步查法:先跑分数,再到审计里点名会动的元素,最后把它的空间提前占住,附一条可复现的命令。

cumulative layout shift(CLS,累计布局偏移)量的是页面加载时内容跳动的幅度。它是第三个 Core Web Vital,目标是在第 75 百分位上 不高于 0.1;超过 0.25 算差。这一章给你一条四步的查法:先把分数跑出来,再到审计里点名那个会动的元素,最后把它的位置提前占住,让它不再乱跳。
读这篇前
你只需要一个能改的页面和浏览器,不用装任何东西。这一章写给已经上线、能改前端代码的人;如果页面现在还改不动,先把那一层解决,再回来看这一步。另外两个 Core Web Vital 各有专章:largest contentful paint 管加载,interaction to next paint 管响应,这一章管第三个:视觉稳定性。想看一批真实站点在加载侧的表现,可以看实测的 total blocking time 实测。
cumulative layout shift 到底在量什么
当某个可见元素在一帧到下一帧之间改变了起始位置,就发生了一次布局偏移。cumulative layout shift 的定义是「一次页面生命周期内,所有非预期布局偏移里得分最大的那一簇」(web.dev,2026-10-01 访问)。要抓住的词是非预期:轮播图自己翻页会造成偏移,用户点一下才翻页就不算,因为浏览器会把真实输入后 500 毫秒内的偏移排除在外。
单次布局偏移的分数,是两个比例相乘。一个是影响比例:发生位移的元素在移动前后覆盖了视口的多少面积,按整个视口算。另一个是距离比例:动得最远的那个元素移动了多远,按视口更长的边算。两者相乘就是这一跳的分数——一条占半屏的横幅往下掉四分之一屏高,得分就是 0.75 × 0.25 = 0.1875。
布局偏移不是「页面在动」,而是「你没让它动,它却动了」。
CLS 不是把所有偏移加起来,而是取最大的那个会话窗口:一秒内接连发生的偏移归为一组,整个窗口最多算五秒。所以加载早期一次明显的跳动,就足以定下你这一页的分数,哪怕后面一直很稳。这也是为什么修好一个元素的收益,常常大过修一百个小元素。
还有一个容易忽略的点:Google 看的不是某一次打开的数字,而是真实用户在第 75 百分位上的表现。同一个页面,用新设备的用户可能一直停在 0.02,慢设备和弱网上的用户却可能连着几次跳到 0.4。实验室里跑出来的一个数,只是这条分布里的一个采样;要按最差的那一段去修,而不是按你本机的那一次。
按这个顺序做
四步,每一步都有一个能核对的完成标志,过不了就别往下走。
- 先把分数跑出来。对线上地址跑下面这条命令。完成标志:拿到一个 CLS 值,并知道它落在哪一档——0.1 以内、0.1 到 0.25、还是超过 0.25。
- 找到元素,不是找到板块。读
layout-shifts审计。完成标志:你能说出具体是哪个节点——某张<img>、某个<iframe>、还是一次字体替换——而不是「页面顶部」。 - 先占位,再谈优化。给那个元素写死宽高,或者用 CSS 的
aspect-ratio。完成标志:它在加载前后占据的是同一个盒子。 - 再跑一遍对比。同一条命令、同一个页面。完成标志:分数降下来了,而且那个元素从偏移列表里消失。
位置比速度重要。把空间预留出来,偏移就没了;只把文件压小,只是让它晚一点跳。
交付物:一张成因表 + 一条审计命令
你真正会遇到的偏移,几乎都出自四种成因。下表把每种成因对上「审计里长什么样」和「真正能修的那一步」。
| 成因 | 审计里的样子 | 真正的修法 |
|---|---|---|
| 图片或 iframe 没声明尺寸 | "Media element lacking an explicit size" | 写 width 与 height 属性,或 CSS 的 aspect-ratio |
| 网页字体换进来时尺寸不同 | "Web font loaded" | font-display: swap 或 optional,再加预加载与 size-adjust |
| 广告、嵌入块或挂件自带盒子 | 页面中间冒出一个没有尺寸的元素 | 给这个位置写死 min-height |
| 请求返回后才追加的内容 | 数据一到,文字或卡片整体移动 | 先用同样尺寸的占位块渲染 |
审计就一行命令,读的是浏览器里 Lighthouse 打印的同一份 JSON。
npx lighthouse https://example.com/ \
--only-audits=cumulative-layout-shift,layout-shifts \
--output=json --output-path=cls.json --quiet
2026-10-01 拿它对 BBC News 跑一次,返回的 cumulative layout shift 是 0.764,列出四次偏移。其中三次,分值 0.710、0.054、0.038,都被标成 "Media element lacking an explicit size";第四次 0.003,是网页字体替换。
| Shift 分数 | 成因 |
|---|---|
| 0.710 | Media element lacking an explicit size |
| 0.054 | Media element lacking an explicit size |
| 0.038 | Media element lacking an explicit size |
| 0.003 | Web font loaded |
把它读成「一个页面、抓一次」,不要当成对这个站点的结论。它是这条命令的演示,恰好显示出最常见的那两种成因。两次成因就覆盖了全部得分。
如果你要把这个数字放进长期监控,记得它会被一次上线重新引入:换了个字体、加了个广告位、把图片改成懒加载,都可能让偏移回来。它值得在每次上线之后重跑一次,而不是只在改版时才想起来。
做错了会怎样
下面三种错法最常见,而且在网速快的机器上用浏览器看,都像是已经修好了。
- 只修图片,不修盒子。压缩文件、放到 CDN 上,只会让它来得快一点,偏移照旧。只要浏览器提前不知道尺寸,图片落地的那一刻布局还是会动。要给的是元素的宽高。
- 只调字体显示,不管替代字体。
font-display: swap消掉的是文字隐形的那段等待,替代字体尺寸不同,整行仍会重排。要配上size-adjust,或者把网页字体预加载,让它跟着样式表一起到。 - 只看实验室数字。实验室工具在模拟环境里加载页面,只能看到加载期发生的偏移。真实用户的 field CLS 可能更高,因为它还算上了用户滚动、点按之后发生的事。
常见问题
cumulative layout shift 多少算好?
在第 75 百分位的页面加载上不高于 0.1,移动端与桌面端分开算。超过 0.25 算差。0.1 是目标,不是每一次访问都要过的线——按第 75 百分位算,意味着你仍有四分之一左右的加载会比它更差。
怎么找出到底是什么造成了布局偏移?
跑 layout-shifts 审计,它会逐条列出偏移、移动的节点,以及多数情况下的原因。原因很粗:「Media element lacking an explicit size」指的是一类问题,不是某一张图。接下来你要按尺寸和位置去定位元素,而不是靠内容去猜。
cumulative layout shift 影响 SEO 吗?
它是 Core Web Vital,而 Core Web Vitals 是 Google page experience 信号的一部分。它对真实用户真正改变的是——手指能不能点中原本瞄准的那个东西。所以把差分数当成一个「被计入了排名」的用户问题,而不是一根可以单独拉的排名杠杆。
CLS 会是负数,或者被清零吗?
不会为负,它是若干正数相加,永远不小于零。从往返缓存里恢复页面时它确实会归零,因为浏览器把那次当成一次新的访问。我们没测出来任何工具会报负值,也查不到有据可查的案例。
边界要说清楚:这一套量的是实验室里的加载期偏移,它看不到读者滚动三十秒之后广告造成的那一跳。这不代表这个数字没用——它意味着这是一个下限。先把空间占住,把加载期的分数压到零,再盯 field 数字看之后会发生什么。把落地页上的这个数字长期盯住,正是 QueryWin 在做的事。
本文属于 QueryWin 实操手册 · 第 2 阶


