這篇文章已經在草稿箱裡放了好久,考慮一下還是發布吧。這是翻譯的文章,原文在這裡Efficiently Rendering CSS
我們寫的CSS有多高效?換個說法,瀏覽器渲染我們的CSS會有多快?我承認這個問題我考慮的不夠多
這個問題本應該是瀏覽器廠商考慮的——他們的瀏覽器越快,使用者就越喜歡用他們的產品。Mozilla有一篇關於這方面最佳實務的文章,一直堅持Web應該更快的Google也有一篇。
我們一起看看他們闡釋的一些主要觀點,然後探討一下這些原則的實用價值
從右向左
瀏覽器如何讀取你的CSS選取器?我們需要明白的最重要的一點是從右向左。比如這個選取器ul > li a[title="home"]
,瀏覽器首先讀取的是a[title="home"]
。這個首先被讀取的部分我們叫它key selector
,它是瀏覽器最終要選擇的元素。
ID最快,Universal最慢
有四種類型的key selector
,解析速度由快到慢依次是:ID、class、tag和universal
#main-navigation { } /* ID(最快) */
body.home #page-wrap { } /* ID */
.main-navigation { } /* Class */
ul li a.current { } /* Class *
ul { } /* Tag */
ul li a { } /* Tag */
* { } /* Universal(慢) */
#content [title='home'] /* Universal */
我們把這個原則與從右向左結合來看,就會發現下面這個選取器並不是很快
#main-nav > li { } /* 比它看起來的要慢 */
這真有點違反我們的直覺。。。由於ID很快,我們直覺的以為瀏覽器會迅速的找到#main-nav
,然後找到它的孩子li
。但實際上,瀏覽器首先解析的是相對較慢的li
不要tag-qualify
永遠不要這樣做
ul#main-navigation { }
ID已經是唯一的,不需要Tag來標識,這樣做會讓選取器變慢。
如果你可以,也盡量不要在class上這樣用。class不是唯一的,你可以用它來處理很多不同的元素。如果你希望擁有同一個class的元素有不同的樣式,你可能需要tag-qualify(比如li.first
),但這是很少見的。
後代選取器最糟糕
David Hyatt這樣說過
The
descendant selector is the most expensive selector in CSS. It is
dreadfully expensive — especially if the selector is in the Tag or
Universal Category.
換句話說,下面這個選取器是很低效的
html body ul li a { }
匹配失敗的選取器更高效
我不清楚從這裡面我們可以學到什麼,在自己的CSS檔案裡寫很多沒用的東西豈不是很奇怪。但還是應該說明一下,當從右向左的解析一個選取器時,如果沒有匹配的結果,瀏覽器將會停止下一步的動作,於是更高效了。。。
想清楚你為什麼這樣寫
考慮這樣一個選取器
#main-navigation li a { font-family: Georgia, Serif; }
font-family
是可以級聯的,所以你可能根本不需要如此特殊的一個選取器(如果你只是要改變字型的話)。這樣做會更高效,而且是高效很多
#main-navigation { font-family: Georgia, Serif; }
CSS3的效率問題
David Hyatt的一些杯具說法:
The sad truth about CSS3 selectors is that they really shouldn’t be used at all if you care about page performance.
CSS3選取器(比如 :nth-child)能夠漂亮的定位我們想要的元素,又能保證我們的CSS整潔易讀。但是這些神奇的選取器會浪費很多的瀏覽器資源。
那該怎樣做?我們真的不應該使用它們嗎?讓我們考慮一些實用的東西
實用性
記
得我在上面列出的Mozilla那篇文章嗎?得有10年之久了。事實上,10年前的電腦是很慢的。我覺得這些在過去是很重要的東西。10年前我21歲,我
甚至不知道CSS是什麼,囧,不知道怎麼翻譯。。。我覺得現在我們很少談論CSS渲染的效率問題或許是因為這已經不再是個大問題了。
我是這樣認為的:不管怎樣,我們上面談論的最佳實務都是有作用的。你可以遵守這些規則,因為他們並不會限制你CSS的能力。但也大可不必把它們當作教條執行。
如果你的網站正好非常緩慢,而你之前並沒有考慮過這些CSS最佳實務,你可能需要好好檢查一下你的CSS了。如果你的網站沒有任何緩慢的跡象,那可以不用理它,以後寫CSS時注意就好了。
極速卻不實用
我
們知道了ID是最高效的選取器。如果你想要一個渲染最快的網頁,那你可以給頁面上每一個元素一個唯一的ID,然後樣式化每一個ID。這將會超級快,但也是
極其滑稽的。這可能讓你的CSS檔案很難讀很難維護。在一些對效能要求很高的硬式編碼網站上你都很難看到這種寫法。我們不應該為了效率而犧牲可讀性和可維
護性。
感謝Jason Beaudoin告訴我這些想法。如果有人瞭解更多相關的東西,或者你需要補充些什麼,那就告訴大家吧。
簡單說一點,很多的JavaScript庫都使用了CSS選取器,上面的原則也依然適用。ID是最快的,而複雜的後代選取器會比較慢。