1. 程式人生 > >轉載:為什麼CSS選擇器是從右往左解析

轉載:為什麼CSS選擇器是從右往左解析

一、CSS選擇器的解析順序
相信很多人在一開始接觸CSS的時候都會看到一條規則就是儘量少使用層級關係,比如儘量不要寫成:

#div P.class {
color: red;
}
1
2
3
而是寫成:

.class {
color: red;
}
1
2
3
之所以需要這麼寫,給的解釋是這樣可以減少選擇器匹配的次數(推薦一個CSS規範的網站)。初看覺得哦,有點道理啊,但是往細了再想想:如果我把層級定的足夠的清晰分明,那不是可以直接去掉很多不對應的CSS選擇器的索引路徑的麼?為什麼都是建議少使用層級關係呢?

原因其實很簡單,我們犯了一個經驗主義錯誤,預設CSS選擇器是從左往右進行解析的,實際上恰恰相反,CSS選擇器是從右往左解析的。

這個事實是不是很顛覆一般的認識?可能這裡很多人就要問了,為什麼瀏覽器廠商要搞出這種反人類的解析順序?難道CSS也跟JS一樣當初幾個瀏覽器廠商互相之間大打出手怎麼讓你彆扭怎麼來?這裡這個鍋就不讓巨硬背了(巨硬:怎麼老是我。。。),其實之所以要這麼做是為了更快的找到對應的樣式,這裡我推薦一下winter老師的一個分享,這篇文章說白了只能算是這個視訊的一篇筆記罷了。。。

二、CSS選擇器進行優化的必要性
OK,具體的情況具體分析,我們先來看一看瀏覽器的渲染過程,如圖:



在圖中我們可以看到HTML解析出了一顆DOM tree,與此同時樣式指令碼則解析生成了一個style rules,也可以說是一個CSS tree。最後,DOM tree同style rules一同結合解析出一顆Render Tree,而Render Tree就是包含了一個dom物件以及為其計算好的樣式規則,提供了佈局以及顯示方法。

因為不清楚一個DOM物件上究竟對應著哪些樣式規則,所以只能選擇一個最笨的辦法,即每一個DOM物件都遍歷一遍style rules,DOM物件的數量相信大家也都清楚,如果每次遍歷style rules都是像一個晒太陽的老大爺一樣的悠哉遊哉,那麼滑鼠廠商應該會很開心,嗯,摔壞了正好買新的嘛~~~因此對CSS選擇器進行優化就是一個必須的事情了。

三、從右往左解析到底好在哪裡
假如有如下的一段HTML:

<div id="div1">
<div class="a">
<div class="b">
...
</div>
<div class="c">


<div class="d">
...
</div>
<div class="e">
...
</div>
</div>
</div>
<div class="f">
<div class="c">
<div class="d">
...
</div>
</div>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
和如下的CSS:

#div1 .c .d {}
.f .c .d {}
.a .c .e {}
#div1 .f {}
.c .d{}
1
2
3
4
5
假如我們的CSS解析器是從左往右進行匹配的,那麼會生成如下的style rules:

 

首先,#div1 .c .d {} .f .c .d {}.c .d{}這三個選擇器裡面都含有 .c .d{}這麼一個公用樣式,所以哪怕是我們的DOM節點明確了是在#div1下面都必須對style rules進行全部的匹配查詢,這樣一來基本上可以說是每一個DOM節點都必須完全遍歷一遍style rules,不然搞不好就會漏掉一些公用樣式之類的,所以想著將層級寫的更加詳細就能去掉很多不對應的CSS選擇器的索引路徑的就不要想了,不管你寫的多細,你總是需要把整個style rules都遍歷一遍,不然萬一漏掉了某個公用樣式不就思密達了?
那麼如果我們換成從右向左進行解析就能夠避免這種情況了麼?請看下面這個style rules:

 

別的先不提,最少這個節點就少了很多嘛,哪怕我這裡同樣是需要全部遍歷一遍就衝著減少了這麼多個節點也要從右往左進行解析啊!
更重要的是,只要有公用樣式,那麼選擇器最右邊的那個型別選擇器一定是相同的,如此公共樣式就很自然的都集中到一個分支上,這個時候我們完全可以將其他不匹配的路徑全部去掉而不用擔心會漏掉某些個公用樣式了。雖然當這顆CSS樹在遍歷的時候還有有部分節點會遍歷到最後才能確定到底是不是匹配的,但總的來說從右往左進行解析還是會比從左往右解析要少很多次的匹配,這樣帶來的效率提升是顯而易見的!

同時,這也是不建議使用*萬用字元來進行樣式匹配的原因:瀏覽器專門建立了一個反常規思維的從右往左的匹配規則就是為了避免對所有元素進行遍歷,你直接一個萬用字元等於之前的工作都白做了。

最後,從右往左進行解析還有一個好處那就是從右往左進行匹配的時候,匹配的全部是DOM元素的父節點,而從左往右進行匹配的時候時候,匹配的全部是DOM元素的子節點,這樣就避免了HTML與CSS沒有下載完需要進行等待的情形。

以上就是我所理解的為什麼CSS選擇器是從右往左解析的原因,如有錯誤歡迎大家進行指正。
---------------------
作者:津泊客
來源:CSDN
原文:https://blog.csdn.net/jinboker/article/details/52126021
版權宣告:本文為博主原創文章,轉載請附上博文連結!