新聞中心
結(jié)合現(xiàn)代網(wǎng)站的復(fù)雜性和瀏覽器處理CSS的方式,即使是適量的CSS也會(huì)成為設(shè)備受限、網(wǎng)絡(luò)延遲、帶寬或數(shù)據(jù)限制的瓶頸。因?yàn)樾阅苁怯脩趔w驗(yàn)的一個(gè)至關(guān)重要的部分,所以必須確保在各種形狀和尺寸的設(shè)備上提供一致的高質(zhì)量體驗(yàn),這也需要優(yōu)化你的CSS。

本篇文章將涵蓋CSS會(huì)導(dǎo)致哪些性能問(wèn)題,以及如何制作不妨礙人們使用的CSS的最佳實(shí)踐。
目錄
- CSS是如何工作的?
- 注意CSS的大小
- 優(yōu)先考慮關(guān)鍵的CSS
- 使用高效的CSS動(dòng)畫(huà)
- 使用CSS優(yōu)化字體加載
- 不用擔(dān)心CSS選擇器的速度問(wèn)題。
CSS是如何工作的?
CSS阻止渲染
當(dāng)一個(gè)頁(yè)面有CSS可用時(shí),無(wú)論是內(nèi)聯(lián)還是外部樣式表,瀏覽器都會(huì)延遲渲染,直到CSS被解析。這是因?yàn)闆](méi)有CSS的頁(yè)面通常是不可用的。如果瀏覽器向你展示了一個(gè)沒(méi)有CSS的亂七八糟的頁(yè)面,然后片刻后又啪啪啪地進(jìn)入了一個(gè)有樣式的頁(yè)面,不斷變化的內(nèi)容和突如其來(lái)的視覺(jué)變化會(huì)讓用戶體驗(yàn)混亂。這種糟糕的用戶體驗(yàn)有一個(gè)名字--Flash of Unstyled Content(FOUC)。
CSS可以阻止HTML的解析
盡管瀏覽器在完成CSS解析之前不會(huì)顯示內(nèi)容,但它會(huì)處理HTML的其余部分。然而腳本會(huì)阻止解析器,除非它們被標(biāo)記為defer或async。一個(gè)腳本有可能操縱頁(yè)面和其余代碼,所以瀏覽器必須注意該腳本的執(zhí)行時(shí)間。
屏蔽腳本的解析器:腳本如何屏蔽HTML解析。
因?yàn)槟_本可以影響應(yīng)用到頁(yè)面的樣式,如果瀏覽器仍在處理一些CSS,它就會(huì)等到處理完畢再運(yùn)行腳本。因?yàn)樵谀_本運(yùn)行之前不會(huì)繼續(xù)解析文檔,這意味著CSS不再只是阻止渲染--取決于文檔中外部樣式表和腳本的順序,也可能停止HTML解析。
解析器阻塞CSS:CSS如何阻塞HTML解析。
為了避免阻塞解析,請(qǐng)盡快交付CSS,并以最佳順序安排你的資源。
注意CSS的大小
壓縮和最小化CSS
建立連接來(lái)下載外部樣式表不可避免地會(huì)造成延遲,但你可以通過(guò)最小化網(wǎng)絡(luò)傳輸?shù)目傋止?jié)來(lái)加快下載速度。
壓縮文件可以顯著提高速度,許多托管平臺(tái)和CDN都會(huì)在默認(rèn)情況下對(duì)資產(chǎn)進(jìn)行壓縮編碼(或者你可以輕松配置)。服務(wù)器和客戶端交互中使用最廣泛的壓縮格式是Gzip。還有Brotli,它可以提供更好的壓縮效果,盡管它不像 Gzip 那樣受到支持。
最小化是去除空白和任何不必要的代碼的過(guò)程。輸出的是一個(gè)更小但完全有效的代碼文件,瀏覽器可以解析,這將為你節(jié)省一些字節(jié)。Terser是一個(gè)流行的JavaScript壓縮工具,如果你使用webpack,v4包含一個(gè)插件來(lái)創(chuàng)建minified的構(gòu)建文件。
微調(diào):刪除未使用的CSS
在使用CSS框架的時(shí)候,最終得到未使用的 CSS 是相對(duì)常見(jiàn)的(除非我們只包含我們需要的組件)。同樣的問(wèn)題也出現(xiàn)在長(zhǎng)期增長(zhǎng)的大型代碼庫(kù)中。
去除未使用的CSS通常是手工操作。主要的挑戰(zhàn)在于它有多么復(fù)雜。我們必須在所有可能的狀態(tài)下,在所有可能的設(shè)備上仔細(xì)審核整個(gè)網(wǎng)站(以覆蓋媒體查詢),并執(zhí)行所有可能改變樣式的JavaScript功能。UnusedCSS和PurifyCSS是流行的工具,可以幫助查明不必要的樣式,但我們應(yīng)該配合仔細(xì)的視覺(jué)回歸測(cè)試。
在這里,使用CSS-in-JS的顯著優(yōu)勢(shì):每個(gè)組件內(nèi)渲染的樣式都是只需要CSS。在CSS-in-JS中加快CSS的秘訣是將CSS內(nèi)聯(lián)到頁(yè)面中,或者將其提取到外部CSS文件中。將CSS發(fā)送到一個(gè)JavaScript文件中會(huì)導(dǎo)致它的解析和緩慢計(jì)算。
優(yōu)先考慮關(guān)鍵的CSS
關(guān)鍵的CSS是一種技術(shù),它提取并內(nèi)嵌CSS以獲得頁(yè)面以上的內(nèi)容。在HTML文檔的
中內(nèi)聯(lián)提取的樣式,無(wú)需額外請(qǐng)求獲取這些樣式,并加快渲染速度。你知道嗎?Above-the-fold是指瀏覽者在滾動(dòng)之前在頁(yè)面加載時(shí)看到的所有內(nèi)容。由于有許多設(shè)備和屏幕尺寸,所以沒(méi)有一個(gè)普遍定義的像素高度被認(rèn)為是折疊以上的內(nèi)容。
為了最大限度地減少首次渲染的往返次數(shù),將上述內(nèi)容保持在14KB(壓縮)以下。
確定關(guān)鍵的CSS并不完全準(zhǔn)確,因?yàn)槟阈枰獙?duì)折疊位置進(jìn)行假設(shè)(不同設(shè)備屏幕尺寸的折疊位置有所不同)。這對(duì)于高度動(dòng)態(tài)的網(wǎng)站來(lái)說(shuō)是很困難的。即使不精確,它仍然可以帶來(lái)性能的提升,我們可以通過(guò)Critical、CriticalCSS和Penthouse等工具自動(dòng)化。
異步加載CSS
CSS的其余部分(不太關(guān)鍵的部分)最好是異步加載。實(shí)現(xiàn)的方法是將link media屬性設(shè)置為print。
"Print"媒體類型定義了用戶試圖打印頁(yè)面時(shí)的樣式表規(guī)則,瀏覽器將在不延遲頁(yè)面渲染的情況下加載這種樣式表。當(dāng)樣式表加載完成后,將該樣式表應(yīng)用于所有媒體(即屏幕而不僅僅是打印),使用onload屬性將媒體設(shè)置為all。
另一種方法是使用
- 瀏覽器對(duì)預(yù)加載的支持還不是很好,所以需要一個(gè)polyfill(或者使用loadCSS等庫(kù))來(lái)跨瀏覽器應(yīng)用樣式表。
- 預(yù)加載會(huì)很早地以最高優(yōu)先級(jí)獲取文件,可能會(huì)降低其他重要下載的優(yōu)先級(jí)。
如果你確實(shí)想要預(yù)加載提供的高優(yōu)先級(jí)獲取(在支持它的瀏覽器中),loadCSS的創(chuàng)建者建議你把它和第一種模式結(jié)合起來(lái),就像這樣。
避免在CSS文件中使用@import
在CSS文件中使用@import會(huì)降低渲染速度。首先,瀏覽器必須下載CSS文件來(lái)發(fā)現(xiàn)導(dǎo)入的資源,然后在渲染之前發(fā)起另一個(gè)請(qǐng)求來(lái)下載它。
如果你有一個(gè)包含@import url(import.css)的樣式表;網(wǎng)絡(luò)瀑布看起來(lái)像這樣。
在link元素中加載兩個(gè)樣式表,允許并行下載。
使用高效的CSS動(dòng)畫(huà)
當(dāng)你對(duì)頁(yè)面上的元素進(jìn)行動(dòng)畫(huà)處理時(shí),瀏覽器經(jīng)常要重新計(jì)算它們?cè)谖臋n中的位置和大小,從而觸發(fā)布局。例如,如果改變了一個(gè)元素的寬度,它的任何一個(gè)子元素都可能受到影響,頁(yè)面布局的很大一部分可能會(huì)改變。布局幾乎總是適用于整個(gè)文檔,所以布局樹(shù)越大,它執(zhí)行布局計(jì)算的時(shí)間就越長(zhǎng)。
當(dāng)動(dòng)畫(huà)元素時(shí),必須盡量減少布局和重繪。并非所有的CSS動(dòng)畫(huà)技術(shù)都是一樣的,現(xiàn)代瀏覽器可以通過(guò)位置、比例、旋轉(zhuǎn)和不透明度來(lái)最好地創(chuàng)建性能優(yōu)異的動(dòng)畫(huà)。
- 不要改變高度和寬度屬性,而是使用transform:scale()。
- 要移動(dòng)元素,避免改變top、right、bottom或left屬性,而使用transform: translate()。
- 如果你想模糊背景,可以考慮使用模糊的圖像并改變其不透明度。
微調(diào):contain屬性
contain CSS 屬性告訴瀏覽器,該元素及其子元素被認(rèn)為是獨(dú)立于文檔樹(shù)的(盡可能)。它將頁(yè)面的子樹(shù)與其他部分隔離開(kāi)來(lái)。這樣瀏覽器就可以優(yōu)化頁(yè)面獨(dú)立部分的渲染(樣式、布局和繪制操作)以提高性能。
contain 屬性在包含許多獨(dú)立小組件的頁(yè)面上非常有用??梢允褂盟鼇?lái)防止每個(gè)小組件內(nèi)的更改在小組件的邊界框外產(chǎn)生副作用。一個(gè)大部分是靜態(tài)的網(wǎng)站將不會(huì)從這個(gè)策略中得到什么好處。
使用CSS優(yōu)化字體加載
避免在加載字體時(shí)出現(xiàn)不可見(jiàn)的文字
字體通常是需要一段時(shí)間來(lái)加載大文件。一些瀏覽器會(huì)隱藏文本,直到字體加載完畢(導(dǎo)致 "不可見(jiàn)文本的閃爍 "或FOIT)來(lái)處理這個(gè)問(wèn)題。在優(yōu)化速度時(shí),你會(huì)希望避免 "不可見(jiàn)文本的閃爍",并使用系統(tǒng)字體(預(yù)裝在機(jī)器上的字體)立即向人們展示內(nèi)容。一旦加載了字體文件,它就會(huì)取代被稱為 "閃現(xiàn)的不規(guī)則文本 "或FOUT的系統(tǒng)字體。
實(shí)現(xiàn)這一目標(biāo)的一種方法是使用font-display--一個(gè)用于指定字體顯示策略的API。使用帶有值交換的 font-display告訴瀏覽器應(yīng)該立即使用系統(tǒng)字體顯示使用此字體的文本。。
使用可變字體以減少文件大小。
可變字體使字體的許多不同變化能夠被整合到一個(gè)文件中,而不是為每一種寬度、重量或樣式都有一個(gè)單獨(dú)的字體文件。它們讓您可以通過(guò)CSS和一個(gè)@font-face引用來(lái)訪問(wèn)一個(gè)給定字體文件中的所有變化。
當(dāng)你需要多個(gè)字體時(shí),可變字體可以顯著減少文件大小。與其加載常規(guī)和粗體風(fēng)格加上它們的斜體版本,你可以加載一個(gè)包含所有信息的單一文件。
Monotype做了一個(gè)實(shí)驗(yàn),將12種輸入字體組合起來(lái),生成8種權(quán)重,橫跨3種寬度,橫跨斜體和羅馬風(fēng)格。將48種單獨(dú)的字體存儲(chǔ)在一個(gè)可變字體文件中,意味著文件大小減少了88%。
不用擔(dān)心CSS選擇器的速度問(wèn)題。
CSS選擇符的結(jié)構(gòu)方式會(huì)影響瀏覽器匹配它們的速度。瀏覽器從右到左讀取選擇符,所以當(dāng)你使用后代選擇器時(shí)。例如,nav a {},它會(huì)首先匹配頁(yè)面上的每一個(gè) 元素,然后再將nav里面的元素歸零。如果你使用一個(gè)更具體的選擇器,例如,在nav元素內(nèi)的每個(gè) 上使用.nav-link,它就不會(huì)花時(shí)間去匹配頁(yè)面上的每個(gè) 。
如果你考慮瀏覽器是如何從右到左匹配選擇符的,再舉個(gè)例子,比如.container ul li a { },你就會(huì)明白為什么后代選擇器經(jīng)常被貼上 "昂貴 "的標(biāo)簽。
看起來(lái),這樣的選擇器會(huì)是一個(gè)速度問(wèn)題。然而,選擇器匹配性能是很快的。CSS聲明對(duì)壓縮算法非常友好,因此優(yōu)化CSS選擇器所需的努力通常會(huì)更好地用在應(yīng)用程序的其他部分,投資回報(bào)率更高。
CSS對(duì)于加載頁(yè)面和愉快的用戶體驗(yàn)至關(guān)重要。雖然我們通常可能會(huì)優(yōu)先考慮其他資源(如腳本或圖像),因?yàn)樗鼈兏哂绊懥?,但我們不?yīng)該忘記CSS。通過(guò)上述策略,您將能夠確??焖俳桓逗蛨?zhí)行。
網(wǎng)站名稱:如何提高CSS性能
文章路徑:http://www.dlmjj.cn/article/djjesoh.html


咨詢
建站咨詢
