主流程
-
呈現(xiàn)引擎一開始會從網(wǎng)絡層獲取請求文檔的內(nèi)容,內(nèi)容的大小一般限制在 8000 個塊以內(nèi)楚昭。
然后進行如下所示的基本流程:
解析html以構(gòu)造DOM樹————構(gòu)建渲染樹————布局渲染樹————繪制渲染樹
主流程示例:
-
Webkit 主流程(chrome瀏覽器)
-
Mozilla 的 Gecko 呈現(xiàn)引擎主流程(firefox瀏覽器)
-
由圖可以發(fā)現(xiàn)冈涧,兩個引擎過程基本相同茂附。主要有三個步驟:
1.解析。瀏覽器會解析HTML/SVG/XHTML督弓,瀏覽器解析這三種文件會產(chǎn)生一個DOM Tree营曼;解析CSS,產(chǎn)生style rules愚隧;解析Javacript蒂阱,主要通過DOM API和CSSOM API來操作DOM Tree和CSS Rule Tree。
2.解析完成后狂塘,瀏覽器引擎會通過DOM Tree和CSS Rule Tree來構(gòu)造Rendering Tree录煤。
3.調(diào)用操作系統(tǒng)Native GUI的API繪制。
1.解析 HTML 標簽, 構(gòu)建 DOM 樹
2.解析 CSS 標簽, 構(gòu)建 CSSOM 樹
3.把 DOM 和 CSSOM 組合成 渲染樹 (render tree)
為構(gòu)建渲染樹荞胡,瀏覽器大體上完成了下列工作:
- 從 DOM 樹的根節(jié)點開始遍歷每個可見節(jié)點妈踊。
- 某些節(jié)點不可見(例如腳本標記、元標記等)泪漂,因為它們不會體現(xiàn)在渲染輸出中廊营,所以會被忽略。
- 某些節(jié)點通過 CSS 隱藏萝勤,因此在渲染樹中也會被忽略露筒,例如,上例中的 span 節(jié)點---不會出現(xiàn)在渲染樹中敌卓,---因為有一個顯式規(guī)則在該節(jié)點上設置了“display: none”屬性慎式。
visibility: hidden 與 display: none 是不一樣的。前者隱藏元素,但元素仍占據(jù)著布局空間(即將其渲染成一個空框)瘪吏,而后者 (display: none) 將元素從渲染樹中完全移除癣防,元素既不可見,也不是布局的組成部分肪虎。
2.對于每個可見節(jié)點劣砍,為其找到適配的 CSSOM 規(guī)則并應用它們。
3.發(fā)射可見節(jié)點扇救,連同其內(nèi)容和計算的樣式刑枝。
visibility: hidden
與 display: none
是不一樣的。前者隱藏元素迅腔,但元素仍占據(jù)著布局空間(即將其渲染成一個空框)装畅,而后者 (display: none) 將元素從渲染樹中完全移除,元素既不可見沧烈,也不是布局的組成部分掠兄。
最終輸出的是一個包含屏幕上所有可見元素的內(nèi)容和樣式信息的渲染。有了渲染樹锌雀,我們就可以進入“布局”階段蚂夕。
4.在渲染樹的基礎上進行布局, 計算每個節(jié)點的幾何結(jié)構(gòu)
到目前為止,我們已經(jīng)計算出哪些節(jié)點應該是可見的和它們所計算出的樣式腋逆,但是我們還沒有在設備的視口中計算出它們的確切位置和大小——這就是“布局”階段婿牍,也稱為“回流”。
為了計算頁面上每個對象的確切大小和位置惩歉,瀏覽器從呈現(xiàn)樹的根元素開始遍歷它等脂。我們看一個簡單的例子:
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Critial Path: Hello world!</title>
</head>
<body>
<div style="width: 50%">
<div style="width: 50%">Hello world!</div>
</div>
</body>
</html>
上述頁面包含兩個嵌套的div:第一個(父)div將節(jié)點的顯示大小設置為視口寬度的50%,而第二個div(被父節(jié)點包含)的寬度為其父元素的50%撑蚌,即視口寬度的25%
布局過程輸出的是一個“盒模型”上遥,它精確地獲取到視口中每個元素的確切位置和大小:所有相對測量值都被轉(zhuǎn)換為屏幕上的絕對像素争涌。
5.把每個節(jié)點繪制到屏幕上 (painting)
最后粉楚,現(xiàn)在我們知道哪些節(jié)點是可見的,以及它們的計算樣式和幾何圖形亮垫,我們可以將這些信息傳遞到最后一個階段解幼,它將渲染樹中的每個節(jié)點轉(zhuǎn)換為屏幕上的實際像素。這一步通常被稱為“繪制”或“柵格化”包警。
上述步驟都需要瀏覽器完成大量工作,所以相當耗時底靠。不過害晦,Chrome DevTools 可以幫助我們對上述所有三個階段進行深入的了解。讓我們看一下最初“hello world”示例的布局階段:
- “Layout”事件在時間線中捕獲渲染樹構(gòu)建以及位置和尺寸計算。
- 布局完成后壹瘟,瀏覽器會立即發(fā)出“Paint Setup”和“Paint”事件鲫剿,將渲染樹轉(zhuǎn)換成屏幕上的像素。
執(zhí)行渲染樹構(gòu)建稻轨、布局和繪制所需的時間將取決于文檔大小灵莲、應用的樣式,以及運行文檔的設備:文檔越大殴俱,瀏覽器需要完成的工作就越多政冻;樣式越復雜,繪制需要的時間就越長(例如线欲,單色的繪制開銷“較小”明场,而陰影的計算和渲染開銷則要“大得多”)。