DOM和CSS渲染過程摘抄-021

DOM和CSS渲染過程

DOM

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
</html>

一個簡單的html頁面如上所示。css

DOM有兩個概念:html

  • 解析
  • 渲染

DOM解析

DOM解析:就是把你所寫的各類html標籤,生成一個DOM TREE,能夠認爲就是生成了一個最原始的頁面,一點樣式都沒有,毫無CSS修飾。web

DOM渲染:瀏覽器會把自己默認的樣式+用戶本身寫得樣式整合到一塊兒,造成一個CSS TREE,而DOM渲染就是指DOM TREE 和 CSS TREE 結合到一塊兒,生成一個Render TREE,呈現出一個帶有樣式的頁面。瀏覽器

clipboard.png

1)瀏覽器會解析三個東西:多線程

一個是HTML/SVG/XHTML,事實上,Webkit有三個C++的類對應這三類文檔。解析這三種文件會產生一個DOM Tree。
CSS,解析CSS會產生CSS規則樹。
Javascript,腳本,主要是經過DOM API和CSSOM API來操做DOM Tree和CSS Rule Tree.
2)解析完成後,瀏覽器引擎會經過DOM Tree 和 CSS Rule Tree 來構造 Rendering Tree。注意:異步

Rendering Tree 渲染樹並不等同於DOM樹,由於一些像Header或display:none的東西就不必放在渲染樹中了。
CSS 的 Rule Tree主要是爲了完成匹配並把CSS Rule附加上Rendering Tree上的每一個Element。也就是DOM結點。也就是所謂的Frame。
而後,計算每一個Frame(也就是每一個Element)的位置,這又叫layout和reflow過程。
3)最後經過調用操做系統Native GUI的API繪製。async

線程

js 是單線程,可是瀏覽器是多線程的。佈局

瀏覽器會有不一樣的線程,好比說優化

  • GUI 渲染線程
  • JS 線程
  • 定時器觸發線程 (setTimeout)
  • 瀏覽器事件線程 (onclick)
  • http 異步線程
  • .....

上面的幾個線程,在同一個瞬間,只有一個線程起做用,也就是互斥的。好比說瀏覽器在執行GUI 渲染線程呢,那麼其餘的4個進程,都處於掛起的狀態,在隊列裏面呆着。
DOM的渲染對應的就是GUI渲染進程;JS的執行對應的就是JS線程;因此,DOM的渲染與JS代碼的運行,在同一瞬間只能有一個執行!ui

阻塞

阻塞XXX是指讓XXX暫停了。好比JS的執行阻塞DOM解析,就是

DOM解析 --> JS執行(此時DOM解析暫停) --> JS執行完畢 --> DOM繼續解析

DOM與CSS

先看它倆之間的關係,也就是分析CSS的加載對DOM的解析和渲染的影響。
很明顯,DOM本身在那解析DOM TREE 和 css樣式有啥關係啊,因此css不影響DOM解析。
也很明顯,DOM渲染就是要生成樣式呢,確定和css有關係啊,因此css影響DOM渲染。
結論:

  • css的加載不會阻塞DOM的解析
  • css的加載會阻塞DOM的渲染

DOM與JS

JS(加載和執行) 都會阻塞 DOM 的解析,由於JS中可能會對DOM進行操做,可能改變DOM的結構,因此JS的加載和執行是會阻塞DOM解析的。
JS(加載和執行) 都會阻塞 DOM 的渲染,同上面同樣,由於JS中可能對樣式進行操做。
注: html中每遇到< script >標籤,頁面就會從新渲染一次,由於要保證標籤中的JS代碼拿到的都是最新的樣式。
結論:

  • JS的加載和執行會阻塞DOM的解析
  • JS的加載和執行會阻塞DOM的渲染

CSS與JS

在線程那裏說了,CSS的加載會阻塞JS的執行,由於CSS的渲染GUI線程和JS運行線程互斥。
可是CSS不會阻塞JS的加載(瀏覽器能夠預先掃描並下載)
注1:

  • CSS、JS之間的加載是否阻塞,這裏不考慮,由於現代的瀏覽器都會預先偷看文檔,而且下載。

注2:

  • 這裏的JS引入方式不包括async和defer

結論:

  • CSS的加載阻塞JS的運行,不阻塞JS的加載

clipboard.png

Note: 簡單提一句,請注意 visibility: hidden 與 display: none 是不同的。前者隱藏元素,但元素仍佔據着佈局空間(即將其渲染成一個空框),然後者 (display: none) 將元素從渲染樹中徹底移除,元素既不可見,也不是佈局的組成部分。

下面簡要概述了瀏覽器完成的步驟:

  • 處理 HTML 標記並構建 DOM 樹。
  • 處理 CSS 標記並構建 CSSOM 樹。
  • 將 DOM 與 CSSOM 合併成一個渲染樹。
  • 根據渲染樹來佈局,以計算每一個節點的幾何信息。
  • 將各個節點繪製到屏幕上。

優化關鍵渲染路徑_就是指最大限度縮短執行上述第 1 步至第 5 步耗費的總時間

https://developers.google.com...

https://developers.google.com...

https://developers.google.com...

相關文章
相關標籤/搜索