修復(fù) CLS(累計(jì)布局偏移)問(wèn)題的實(shí)戰(zhàn)經(jīng)驗(yàn)分享
你是否遇到過(guò)這樣的情況:正要點(diǎn)擊一個(gè)按鈕,結(jié)果它突然“滑走”了? 這不是錯(cuò)覺(jué),而是 CLS(Cumulative Layout Shift,累計(jì)布局偏移) 在作祟。
CLS 是影響用戶體驗(yàn)和網(wǎng)頁(yè)排名的關(guān)鍵指標(biāo)之一,下面分享我在實(shí)際項(xiàng)目中是如何發(fā)現(xiàn)并修復(fù) CLS 的,希望對(duì)你也有幫助。
什么是 CLS?
CLS 反映的是頁(yè)面在加載過(guò)程中元素意外移動(dòng)的程度。
數(shù)值越高,說(shuō)明頁(yè)面越不穩(wěn)定 —— 內(nèi)容在加載過(guò)程中“亂跳”,用戶體驗(yàn)自然會(huì)大打折扣。
CLS 常見(jiàn)的幾個(gè)“元兇”
圖片未設(shè)置尺寸
- 沒(méi)有指定
width
和height
,瀏覽器無(wú)法預(yù)留空間,導(dǎo)致圖片加載時(shí)內(nèi)容被擠下去。
廣告、iframe、嵌入內(nèi)容未提前占位
- 動(dòng)態(tài)加載的內(nèi)容會(huì)強(qiáng)行推開(kāi)現(xiàn)有布局,引起嚴(yán)重偏移。
字體加載造成的 FOIT/FOUT
- 自定義字體加載慢,會(huì)導(dǎo)致“閃爍”或文字重排。
JavaScript 插入內(nèi)容沒(méi)預(yù)留空間
- JS 動(dòng)態(tài)插入元素(特別是在頂部)會(huì)影響現(xiàn)有布局。
不合理的動(dòng)畫(huà)
- 使用
height
、margin
、top
等觸發(fā)回流的動(dòng)畫(huà),會(huì)導(dǎo)致頁(yè)面整體抖動(dòng)。
修復(fù) CLS 的實(shí)戰(zhàn)方法
1. 給圖片和視頻明確尺寸
給 <img>
和 <video>
添加 width
和 height
屬性,或通過(guò) CSS 固定尺寸。
<img src="banner.jpg" width="600" height="400" />
或:
img {
width: 600px;
height: 400px;
}
瀏覽器能根據(jù)尺寸預(yù)留空間,避免加載時(shí)布局被“頂開(kāi)”。
2. 動(dòng)態(tài)內(nèi)容提前預(yù)留空間
廣告、iframe 等內(nèi)容必須預(yù)設(shè)高度:
<div style="min-height: 250px;">
<!-- 廣告內(nèi)容異步加載 -->
</div>
不要等內(nèi)容加載后再插入,否則“跳動(dòng)”難以避免。
3. 優(yōu)化字體加載
避免字體加載時(shí)“閃爍”或重排,推薦使用 font-display: swap
:
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-display: swap;
}
頁(yè)面先用系統(tǒng)字體顯示,等字體加載完成再無(wú)感替換。
4. 動(dòng)態(tài)插入內(nèi)容要有策略
不要隨便在頁(yè)面中部或頂部插入新元素,最好:
- 插在頁(yè)面底部;
- 或者提前插入空容器、留好位置。
// 插入評(píng)論區(qū)內(nèi)容
const container = document.getElementById('comments');
container.innerHTML = '<div>加載中...</div>';
5. 使用 transform 替代動(dòng)畫(huà)屬性
動(dòng)畫(huà)推薦使用 transform
和 opacity
,不要用 top
、width
等影響布局的屬性。
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: scale(1.05);
}
transform 不會(huì)觸發(fā)重排,動(dòng)畫(huà)更平滑,也更穩(wěn)定。
如何監(jiān)控和調(diào)試 CLS?
- PageSpeed Insights(谷歌官方)
直接查看 CLS 得分和優(yōu)化建議。
- Chrome DevTools
Performance 面板可分析頁(yè)面加載過(guò)程中的布局偏移。
- WebPageTest
提供逐幀畫(huà)面,可以直觀看出哪里出現(xiàn)了跳動(dòng)。
最后總結(jié)
CLS 是影響用戶體驗(yàn)的隱性殺手,但也完全可以避免:
- 指定所有圖片、視頻的尺寸;
- 廣告和 iframe 內(nèi)容提前占位;
- 字體加載使用
font-display: swap
; - 插入內(nèi)容前留出空間;
- 動(dòng)畫(huà)用 transform,不要?jiǎng)?layout。
布局穩(wěn)定,不僅用戶喜歡,搜索引擎也更青睞。
下次寫(xiě)組件或引入新模塊時(shí),提前考慮“這會(huì)不會(huì)讓布局抖一下”,提前規(guī)劃,效果立竿見(jiàn)影。