渲染树构建、布局及绘制
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?渲染樹構(gòu)建、布局及繪制
CSSOM 樹和 DOM 樹合并成渲染樹,然后用于計(jì)算每個(gè)可見元素的布局,并輸出給繪制流程,將像素渲染到屏幕上。優(yōu)化上述每一個(gè)步驟對(duì)實(shí)現(xiàn)最佳渲染性能至關(guān)重要。
在前面介紹構(gòu)建對(duì)象模型的章節(jié)中,我們根據(jù) HTML 和 CSS 輸入構(gòu)建了 DOM 樹和 CSSOM 樹。 不過,它們都是獨(dú)立的對(duì)象,分別網(wǎng)羅文檔不同方面的信息:一個(gè)描述內(nèi)容,另一個(gè)則是描述需要對(duì)文檔應(yīng)用的樣式規(guī)則。我們?cè)撊绾螌烧吆喜?#xff0c;讓瀏覽器在屏幕上渲染像素呢?
TL;DR
- DOM 樹與 CSSOM 樹合并后形成渲染樹。
- 渲染樹只包含渲染網(wǎng)頁所需的節(jié)點(diǎn)。
- 布局計(jì)算每個(gè)對(duì)象的精確位置和大小。
- 最后一步是繪制,使用最終渲染樹將像素渲染到屏幕上。
第一步是讓瀏覽器將 DOM 和 CSSOM 合并成一個(gè)“渲染樹”,網(wǎng)羅網(wǎng)頁上所有可見的 DOM 內(nèi)容,以及每個(gè)節(jié)點(diǎn)的所有 CSSOM 樣式信息。
為構(gòu)建渲染樹,瀏覽器大體上完成了下列工作:
-
從 DOM 樹的根節(jié)點(diǎn)開始遍歷每個(gè)可見節(jié)點(diǎn)。
- 某些節(jié)點(diǎn)不可見(例如腳本標(biāo)記、元標(biāo)記等),因?yàn)樗鼈儾粫?huì)體現(xiàn)在渲染輸出中,所以會(huì)被忽略。
- 某些節(jié)點(diǎn)通過 CSS 隱藏,因此在渲染樹中也會(huì)被忽略,例如,上例中的 span 節(jié)點(diǎn)---不會(huì)出現(xiàn)在渲染樹中,---因?yàn)橛幸粋€(gè)顯式規(guī)則在該節(jié)點(diǎn)上設(shè)置了“display: none”屬性。
-
對(duì)于每個(gè)可見節(jié)點(diǎn),為其找到適配的 CSSOM 規(guī)則并應(yīng)用它們。
- 發(fā)射可見節(jié)點(diǎn),連同其內(nèi)容和計(jì)算的樣式。
-
注:簡單提一句,請(qǐng)注意 visibility: hidden 與 display: none 是不一樣的。前者隱藏元素,但元素仍占據(jù)著布局空間(即將其渲染成一個(gè)空框),而后者 (display: none) 將元素從渲染樹中完全移除,元素既不可見,也不是布局的組成部分。
最終輸出的渲染同時(shí)包含了屏幕上的所有可見內(nèi)容及其樣式信息。有了渲染樹,我們就可以進(jìn)入“布局”階段。
到目前為止,我們計(jì)算了哪些節(jié)點(diǎn)應(yīng)該是可見的以及它們的計(jì)算樣式,但我們尚未計(jì)算它們?cè)谠O(shè)備視口內(nèi)的確切位置和大小---這就是“布局”階段,也稱為“自動(dòng)重排”。
為弄清每個(gè)對(duì)象在網(wǎng)頁上的確切大小和位置,瀏覽器從渲染樹的根節(jié)點(diǎn)開始進(jìn)行遍歷。讓我們考慮下面這樣一個(gè)簡單的實(shí)例:
- <html><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>
以上網(wǎng)頁的正文包含兩個(gè)嵌套 div:第一個(gè)(父)div 將節(jié)點(diǎn)的顯示尺寸設(shè)置為視口寬度的 50%,---父 div 包含的第二個(gè) div---將其寬度設(shè)置為其父項(xiàng)的 50%;即視口寬度的 25%。
布局流程的輸出是一個(gè)“盒模型”,它會(huì)精確地捕獲每個(gè)元素在視口內(nèi)的確切位置和尺寸:所有相對(duì)測(cè)量值都轉(zhuǎn)換為屏幕上的絕對(duì)像素。
最后,既然我們知道了哪些節(jié)點(diǎn)可見、它們的計(jì)算樣式以及幾何信息,我們終于可以將這些信息傳遞給最后一個(gè)階段:將渲染樹中的每個(gè)節(jié)點(diǎn)轉(zhuǎn)換成屏幕上的實(shí)際像素。這一步通常稱為“繪制”或“柵格化”。
-
上述步驟都需要瀏覽器完成大量工作,所以相當(dāng)耗時(shí)。不過,Chrome DevTools 可以幫助我們對(duì)上述所有三個(gè)階段進(jìn)行深入的了解。讓我們看一下最初“hello world”示例的布局階段:
- “Layout”事件在時(shí)間線中捕獲渲染樹構(gòu)建以及位置和尺寸計(jì)算。
- 布局完成后,瀏覽器會(huì)立即發(fā)出“Paint Setup”和“Paint”事件,將渲染樹轉(zhuǎn)換成屏幕上的像素。
執(zhí)行渲染樹構(gòu)建、布局和繪制所需的時(shí)間將取決于文檔大小、應(yīng)用的樣式,以及運(yùn)行文檔的設(shè)備:文檔越大,瀏覽器需要完成的工作就越多;樣式越復(fù)雜,繪制需要的時(shí)間就越長(例如,單色的繪制開銷“較小”,而陰影的計(jì)算和渲染開銷則要“大得多”)。
-
最后將在視口中看到下面的網(wǎng)頁:
下面簡要概述了瀏覽器完成的步驟:
- 處理 HTML 標(biāo)記并構(gòu)建 DOM 樹。
- 處理 CSS 標(biāo)記并構(gòu)建 CSSOM 樹。
- 將 DOM 與 CSSOM 合并成一個(gè)渲染樹。
- 根據(jù)渲染樹來布局,以計(jì)算每個(gè)節(jié)點(diǎn)的幾何信息。
- 將各個(gè)節(jié)點(diǎn)繪制到屏幕上。
-
我們的演示網(wǎng)頁看起來可能很簡單,實(shí)際上卻需要完成相當(dāng)多的工作。如果 DOM 或 CSSOM 被修改,您只能再執(zhí)行一遍以上所有步驟,以確定哪些像素需要在屏幕上進(jìn)行重新渲染。
_優(yōu)化關(guān)鍵渲染路徑_就是指最大限度縮短執(zhí)行上述第 1 步至第 5 步耗費(fèi)的總時(shí)間。 這樣一來,就能盡快將內(nèi)容渲染到屏幕上,此外還能縮短首次渲染后屏幕刷新的時(shí)間,即為交互式內(nèi)容實(shí)現(xiàn)更高的刷新率。
- 原文出處:https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction
轉(zhuǎn)載于:https://www.cnblogs.com/wengXiaofeng/p/8117529.html
總結(jié)
以上是生活随笔為你收集整理的渲染树构建、布局及绘制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 论MORMOT序列的JSON格式
- 下一篇: Ubantu中安装sublime