cls 应压至 0.1 以内,核心是源头预防位移:为媒体元素预设尺寸、确保字体切换不重排、为动态内容预留空间。需覆盖加载、滚动、点击、广告注入等全生命周期场景。

CLS 要压到 0.1 以内,核心不是“等它发生再修”,而是从页面结构源头掐断意外位移的可能。它不只发生在首屏加载,用户滚动、点击、广告注入、字体替换时都可能累积——所以优化必须覆盖整个生命周期。
给所有媒体元素预设可计算尺寸
图片和视频没留空间,是 CLS 最高频诱因。浏览器初始渲染时按 0×0 占位,资源加载完成才撑开容器,下方内容瞬间下坠。
- 给
<img>显式写width和height属性(不是仅用 CSS),现代浏览器会据此推算宽高比并预留空间 - 响应式场景优先用
aspect-ratio:例如<div style="aspect-ratio: 16/9"><img src="..."></div> - 视频嵌入推荐 padding-top hack:容器设
position: relative; padding-top: 56.25%,内部<iframe></iframe>绝对定位填满
动态内容必须提前画框
广告、评论区、推荐卡片、懒加载模块……只要它们是异步进来的,又没占地方,就会把原有内容往下顶。
- 第三方广告容器直接设固定宽高:
<div class="ad" style="width: 300px; height: 250px;"></div> - 用骨架屏替代空白等待:灰色块高度与真实内容一致,带轻微动画提升感知性能
- JS 插入 DOM 时避免
innerHTML = ...直接覆盖,改用replaceWith()或先渲染占位节点再替换内容
字体切换不引发重排
Web 字体加载慢,系统字体和自定义字体宽度/行高不同,一替换就“跳字”,尤其标题、按钮、导航栏最明显。
- 在
@font-face中强制加font-display: swap,确保文字始终可见 - 用
<link rel="preload">预加载关键字体文件,缩短等待时间 - 避免在 CSS 中用
font-weight或font-size动态调整字体样式,保持 fallback 与最终字体盒模型一致
框架组件也要守规矩
React/Vue 不会自动帮你预留空间。组件挂载时若内部含未约束尺寸的子元素(比如没设宽高的图片或异步数据容器),就会造成 shift。
- 服务端渲染(SSR)或静态生成(SSG)时,首屏关键区块应输出完整 HTML 结构,含占位图或文字
- 用
Suspense时,fallback组件必须和真实组件具有相同盒模型(同宽高、同 margin/padding) - 避免在
useEffect中直接操作 DOM 尺寸(如el.style.height = 'auto'),改用 CSS transitions 或 resize observer
测 CLS 推荐用 Chrome DevTools 的 Performance 面板录制真实交互流程,或 Lighthouse 多次运行取中位数。重点关注首次加载、滚动触底加载、点击展开区域这几个节点。不复杂但容易忽略——核心就三点:给媒体留地、让字体稳着换、为动态内容画框。











