亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

章節
問答
課簽
筆記
評論
占位
占位

CSS的解析原理

在開始前,我們必須了解一個真相為什么排版引擎解析 CSS 選擇器時一定要從右往左析? 

1.HTML 經過解析生成 DOM Tree(這個我們比較熟悉);而在 CSS 解析完畢后,需要將解析的結果與 DOM Tree 的內容一起進行分析建立一棵 Render Tree,最終用來進行繪圖。Render Tree 中的元素(WebKit 中稱為「renderers」,Firefox 下為「frames」)與 DOM 元素相對應,但非一一對應:一個 DOM 元素可能會對應多個 renderer,如文本折行后,不同的「行」會成為 render tree 種不同的 renderer。也有的 DOM 元素被 Render Tree 完全無視,比如 display:none 的元素。

2.在建立 Render Tree 時(WebKit 中的「Attachment」過程),瀏覽器就要為每個 DOM Tree 中的元素根據 CSS 的解析結果(Style Rules)來確定生成怎樣的 renderer。對于每個 DOM 元素,必須在所有 Style Rules 中找到符合的 selector 并將對應的規則進行合并。選擇器的「解析」實際是在這里執行的,在遍歷 DOM Tree 時,從 Style Rules 中去尋找對應的 selector。

3.因為所有樣式規則可能數量很大,而且絕大多數不會匹配到當前的 DOM 元素(因為數量很大所以一般會建立規則索引樹),所以有一個快速的方法來判斷「這個 selector 不匹配當前元素」就是極其重要的。

4.如果正向解析,例如「div div p em」,我們首先就要檢查當前元素到 html 的整條路徑,找到最上層的 div,再往下找,如果遇到不匹配就必須回到最上層那個 div,往下再去匹配選擇器中的第一個 div,回溯若干次才能確定匹配與否,效率很低。

5.逆向匹配則不同,如果當前的 DOM 元素是 div,而不是 selector 最后的 em,那只要一步就能排除。只有在匹配時,才會不斷向上找父節點進行驗證。

6.但因為匹配的情況遠遠低于不匹配的情況,所以逆向匹配帶來的優勢是巨大的。同時我們也能夠看出,在選擇器結尾加上「*」就大大降低了這種優勢,這也就是很多優化原則提到的盡量避免在選擇器末尾添加通配符的原因。

簡單的來說瀏覽器從右到左進行查找的好處是為了盡早過濾掉一些無關的樣式規則和元素

<div>
   <div class="Aaron">
      <p><span>s1</span></p>
      <p><span>s2</span></p>
      <p><span>s3</span></p>
      <p><span class='red'>s4</span></p>
   </div>
</div>

CSS選擇器

div > div.Aaron p span.red{
   color:red;
}

而如果按從左到右的方式進行查找:

1. 先找到所有div節點

2. 第一個div節點內找到所有的子div,并且是class="Aaron"

3. 然后再一次匹配p span.red等情況

4. 遇到不匹配的情況,就必須回溯到一開始搜索的div或者p節點,然后去搜索下個節點,重復這樣的過程。這樣的搜索過程對于一個只是匹配很少節點的選擇器來說,效率是極低的,因為我們花費了大量的時間在回溯匹配不符合規則的節點。

如果換個思路,我們一開始過濾出跟目標節點最符合的集合出來,再在這個集合進行搜索,大大降低了搜索空間。

從右到左來解析選擇器:

則首先就查找到<span class='red'>的元素。

Firefox稱這種查找方式為key selector(關鍵字查詢),所謂的關鍵字就是樣式規則中最后(最右邊)的規則,上面的key就是span.red。

緊接著我們判斷這些節點中的前兄弟節點是否符合p這個規則,這樣就又減少了集合的元素,只有符合當前的子規則才會匹配再上一條子規則。

要知道DOM樹是一個什么樣的結構,一個元素可能有若干子元素,如果每一個都去判斷一下顯然性能太差。而一個子元素只有一個父元素,所以找起來非常方便。你可以看看CSS的選擇器的設計,完全是為了優化從子元素找父元素而決定的。

打個比如 p span.showing

你認為從一個p元素下面找到所有的span元素并判斷是否有class showing快,還是找到所有的span元素判斷是否有class showing并且包括一個p父元素快 ?

所以瀏覽器解析CSS的引擎就是用這樣的算法。

任務

?不會了怎么辦
||

提問題

寫筆記

公開筆記
提交
||

請驗證,完成請求

由于請求次數過多,請先驗證,完成再次請求

加群二維碼

打開微信掃碼自動綁定

您還未綁定服務號

綁定后可得到

  • · 粉絲專屬優惠福利
  • · 大咖直播交流干貨
  • · 課程更新,問題答復提醒
  • · 賬號支付安全提醒

收藏課程后,能更快找到我哦~

使用 Ctrl+D 可將課程添加到書簽

邀請您關注公眾號
關注后,及時獲悉本課程動態

舉報

0/150
提交
取消
全部 精華 我要發布
全部 我要發布
最熱 最新
只看我的

手記推薦

更多

本次提問將花費2個積分

你的積分不足,無法發表

為什么扣積分?

本次提問將花費2個積分

繼續發表請點擊 "確定"

為什么扣積分?