平時咱們幾乎天天都在和瀏覽器打交道,寫出來的頁面頗有可能在不一樣的瀏覽器下顯示的不同。苦逼的前端攻城師們爲了兼容各個瀏覽器而不斷地 去測試和調試,還在腦子中記下各類遇到的BUG及解決方案,而咱們好像並無去主動地關注和了解下瀏覽器的工做原理。若是咱們對此作一點了解,我想在項目 過程當中就能夠根據它有效的避免一些問題以及對頁面性能作出相應的改進。今天咱們主要根據瀏覽器的渲染原理對CSS的書寫性能作一點改進(固然還有JS本篇 文章暫不考慮,後面的文章會作介紹),下面讓咱們一塊兒來揭開瀏覽器的渲染原理這一神祕的面紗吧:php
最終決定瀏覽器表現出來的頁面效果的差別是:渲染引擎 Rendering Engine(也叫作排版引擎),也就是咱們一般所說的「瀏覽器內核」,負責解析網頁語法(如HTML、JavaScript)並渲染、展現網頁。相同的代碼在不一樣的瀏覽器呈現出來的效果不同,那麼就頗有多是不一樣的瀏覽器內核致使的。css
咱們來看一下加載頁面時瀏覽器的具體工做流程(圖一):前端
(圖一)後端
一、解析HTML以重建DOM樹(Parsing HTML to construct the DOM tree ):渲染引擎開始解析HTML文檔,轉換樹中的標籤到DOM節點,它被稱爲「內容樹」。瀏覽器
二、構建渲染樹(Render tree construction):解析CSS(包括外部CSS文件和樣式元素),根據CSS選擇器計算出節點的樣式,建立另外一個樹 —- 渲染樹。dom
三、佈局渲染樹(Layout of the render tree): 從根節點遞歸調用,計算每個元素的大小、位置等,給每一個節點所應該出如今屏幕上的精確座標。佈局
四、繪製渲染樹(Painting the render tree) : 遍歷渲染樹,每一個節點將使用UI後端層來繪製。性能
主要的流程就是:構建一個dom樹,頁面要顯示的各元素都會建立到這個dom樹當中,每當一個新元素加入到這個dom樹當中,瀏覽器便會經過css引擎查遍css樣式表,找到符合該元素的樣式規則應用到這個元素上。測試
注意了:css引擎查找樣式表,對每條規則都按從右到左的順序去匹配。 看以下規則:spa
1
|
#nav li {}
|
看起來很快,實際上很慢,儘管這讓人有點費解#_#。咱們中的大多數人,尤爲是那些從左到右閱讀的人,可能猜測瀏覽器也是執行從左到右匹配規則的, 所以會推測這條規則的開銷並不高。在腦海中,咱們想象瀏覽器會像這樣工做:找到惟一的ID爲nav的元素,而後把這個樣式應用到直系子元素的li元素上。 咱們知道有一個ID爲nav的元素,而且它只有幾個Li子元素,因此這個CSS選擇符應該至關高效。
事實上,CSS選擇符是從右到左進行匹配的。瞭解這方面的知識後,咱們知道這個以前看似高效地規則實際開銷至關高,瀏覽器必須遍歷頁面上每一個li元素並肯定其父元素的id是否爲nav。
1
|
*{}
|
額,這種方法我剛寫CSS的也寫過,卻不知這種效率是差到極點的作法,由於*通配符將匹配全部元素,因此瀏覽器必須去遍歷每個元素,這樣的計算次數多是上萬次!
1
|
ul#nav{} ul.nav{}
|
在頁面中一個指定的ID只能對應一個元素,因此沒有必要添加額外的限定符,並且這會使它更低效。同時也不要用具體的標籤限定類選擇符,而是要根據實際的狀況對類名進行擴展。例如把ul.nav改爲.main_nav更好。
1
|
ul li li li .nav_item{}
|
對於這樣的選擇器,以前也寫過,最後本身也數不過來有多少後代選擇器了,何不用一個類來關聯最後的標籤元素,如.extra_navitem,這樣只須要匹配class爲extra_navitem的元素,效率明顯提高了
對此,在CSS書寫過程當中,總結出以下性能提高的方案:
避免使用通配規則 如 *{} 計算次數驚人!只對須要用到的元素進行選擇
儘可能少的去對標籤進行選擇,而是用class 如:#nav li{},能夠爲li加上nav_item的類名,以下選擇.nav_item{}
不要去用標籤限定ID或者類選擇符 如:ul#nav,應該簡化爲#nav
儘可能少的去使用後代選擇器,下降選擇器的權重值 後代選擇器的開銷是最高的,儘可能將選擇器的深度降到最低,最高不要超過三層,更多的使用類來關聯每個標籤元素
考慮繼承 瞭解哪些屬性是能夠經過繼承而來的,而後避免對這些屬性重複指定規則
選用高效的選擇符,能夠減小頁面的渲染時間,從而有效的提高用戶體驗(頁面越快,用戶固然越喜歡^_^),你能夠看一下CSS selectors Test,這個實驗的重點是評估複雜選擇符和簡單選擇符的開銷。也許當你想讓渲染速度最高效時,你可能會給每一個獨立的標籤配置一個ID,而後用這些ID寫樣式。那的確會超級快,也超級荒唐!這樣的結果是語義極差,後期的維護難到了極點。
但說到底,CSS性能這東西對於小的項目來說可能真的是微乎其微的東西,提高可能也不是很明顯,但對於大型的項目確定是有幫助的。並且一個好的CSS書寫習慣和方式可以幫助咱們更加嚴謹的要求本身。