サマリー:真真切切的體會(huì)到了 CSS 對(duì)用戶體驗(yàn)的影響非常明顯,稍有不慎就是一個(gè)大坑。下面,我們就來(lái)談?wù)?CSS 性能優(yōu)化的問(wèn)題。加載性能減少文件體積,壓縮代碼減少阻塞加載,不要用 import提高并發(fā)(這個(gè)不甚理解)選擇器性能對(duì)整體性能的影響可以忽略不計(jì)了,但是選擇器的考究更多是為了規(guī)范化和可維護(hù)性、健壯性。具體怎么實(shí)施可以參考 Github 的這個(gè)分享:GitHub's CSS Performa
真真切切的體會(huì)到了 CSS 對(duì)用戶體驗(yàn)的影響非常明顯,稍有不慎就是一個(gè)大坑。下面,我們就來(lái)談?wù)?CSS 性能優(yōu)化的問(wèn)題。
加載性能
減少文件體積,壓縮代碼
減少阻塞加載,不要用 import
提高并發(fā)(這個(gè)不甚理解)
選擇器性能
對(duì)整體性能的影響可以忽略不計(jì)了,但是選擇器的考究更多是為了規(guī)范化和可維護(hù)性、健壯性。具體怎么實(shí)施可以參考 Github 的這個(gè)分享:GitHub's CSS Performance by Jon Rohan
渲染性能
渲染性能是 CSS 優(yōu)化最重要的關(guān)注對(duì)象。我們先來(lái)了解一下瀏覽器的渲染機(jī)制。
瀏覽器的渲染機(jī)制
瀏覽器渲染展示網(wǎng)頁(yè)的過(guò)程,大致分為以下幾個(gè)步驟:
解析HTML(HTML Parser)
構(gòu)建DOM樹(DOM Tree)
渲染樹構(gòu)建(Render Tree)
繪制渲染樹(Painting)
慎重選擇高消耗的樣式
什么 CSS 屬性是高消耗的?就是那些繪制前需要瀏覽器進(jìn)行大量計(jì)算的屬性。
box-shadows
border-radius
transparency
transforms
CSS filters(性能殺手)
避免過(guò)分重排(Reflow)
簡(jiǎn)單解釋一下 Reflow:當(dāng)元素改變的時(shí)候,將會(huì)影響文檔內(nèi)容或結(jié)構(gòu),或元素位置,此過(guò)程稱為 Reflow。
怎么減少 Reflow
不要一條一條地修改 DOM 的樣式,預(yù)先定義好 class,然后修改 DOM 的 className
把 DOM 離線后修改,比如:先把 DOM 給 display:none (有一次 Reflow),然后你修改100次,然后再把它顯示出來(lái)
不要把 DOM 結(jié)點(diǎn)的屬性值放在一個(gè)循環(huán)里當(dāng)成循環(huán)里的變量
盡可能不要修改影響范圍比較大的 DOM
為動(dòng)畫的元素使用絕對(duì)定位 absolute / fixed
不要使用 table 布局,可能很小的一個(gè)小改動(dòng)會(huì)造成整個(gè) table 的重新布局
避免過(guò)分重繪(Repaints)
當(dāng)元素改變的時(shí)候,將不會(huì)影響元素在頁(yè)面當(dāng)中的位置(比如 background-color, border-color, visibility),瀏覽器僅僅會(huì)應(yīng)用新的樣式重繪此元素,此過(guò)程稱為 Repaint。
優(yōu)化動(dòng)畫
CSS3 動(dòng)畫是優(yōu)化的重中之重。除了做到上面兩點(diǎn),減少 Reflow 和 Repaints 之外,還需要注意以下方面。
啟用 GPU 硬件加速
GPU(Graphics Processing Unit) 是圖像處理器。GPU 硬件加速是指應(yīng)用 GPU 的圖形性能對(duì)瀏覽器中的一些圖形操作交給 GPU 來(lái)完成,因?yàn)?nbsp;GPU 是專門為處理圖形而設(shè)計(jì),所以它在速度和能耗上更有效率。
GPU 加速可以不僅應(yīng)用于3D,而且也可以應(yīng)用于2D。這里, GPU 加速通常包括以下幾個(gè)部分:Canvas2D,布局合成(Layout Compositing), CSS3轉(zhuǎn)換(transitions),CSS3 3D變換(transforms),WebGL和視頻(video)。
/* * 根據(jù)上面的結(jié)論 * 將 2d transform 換成 3d * 就可以強(qiáng)制開啟 GPU 加速 * 提高動(dòng)畫性能 */ div { transform: translate(10px, 10px); } div { transform: translate3d(10px, 10px, 0); }