今年 11 月我们接了一个 B2B SaaS 的移动端 CLS 问题,0.28,折腾了三个星期才压到 0.03。最后发现是两个"看不见"的组件在挪页面:cookie 同意条和客服窗口。
这类问题麻烦在于责任不清:开发觉得不是自己写的代码,市场觉得组件是现成的,谁都不认领。
症状和一次误判
GSC 报告里移动端 CLS 0.28,桌面端 0.06。Lighthouse 报的位移元素是 hero 下面那段介绍文字。前端第一反应是图片没尺寸,补了两张图的宽高,分数一动不动。
我们用 Performance 录了 10 次移动端加载,Experience 轨道上有三次明显位移,时间点都在 1.8 秒之后。这个时间点说明不是资源加载,是 JS 执行后插进来的东西。
真凶一:cookie 同意条
合规组件在 DOMContentLoaded 后往 body 顶部插了一条 64 像素高的同意条,整页下移。更糟的是它异步加载,有时 1.2 秒到,有时 2.6 秒到,Lighthouse 跑五次有两次抓不到。
改法:把同意条改成 fixed 定位放底部,不占文档流;或者在 HTML 里预留 64 像素占位。我们选 fixed,因为它本来就是临时提示,挡在底部比推开整页合理。
真凶二:客服窗口
客服组件打开时,它的 iframe 从 0 高度撑到 420 像素。窗口本身是 fixed,但它内部有个"推荐问题"列表是普通文档流,加载完把窗口里的标题顶下去。这部分位移照样被算进 CLS。
改法是给 iframe 容器写死高度加 overflow,内部列表自己滚动。改完客服窗口打开时页面纹丝不动。
结果和流程上的收获
三周后移动端 CLS 从 0.28 到 0.03,桌面端从 0.06 到 0.01。
比数字更有用的是一条规矩:任何第三方组件上线前,必须用移动端 4G 跑五次加载,看有没有位移。这条已经写进客户的验收清单,后面新接的客服系统也是这么过的。
一个可复用的检查办法
我们把这个流程做成了三步,客户自己也能跑:
- Chrome DevTools 打开移动端模拟、4G 加 4 倍 CPU 降速,连续刷新五次
- 每次录 Performance,只看 Experience 轨道上的 Layout Shift,记下位移元素和时间点
- 把时间点和网络面板里第三方脚本的加载时间对照,谁在后面就是谁
这个办法不依赖任何付费工具,前端和后端都能上手。真正难的是第五次才复现出来的那种问题——所以次数不能省,一次两次不够。
顺带修掉的一个坑
排查时我们还发现客服组件的脚本和 cookie 组件各自引入了同一份 polyfill,重复下载 34KB。换掉之后移动端 LCP 也顺带好了 0.2 秒。第三方组件的代价通常不止位移一项,趁着排查一起看。
如果你也在查 CLS,别只盯自己的代码。现在页面上一半的位移来自别人塞进来的东西,而且它们往往在页面"看起来加载完了"之后才动手。
元析智能
为软件公司做 SEO 和 GEO 优化