瀏覽器渲染機制

參考來源

1肥败、瀏覽器解析過程

瀏覽器渲染頁面前需要先構建 DOM 和 CSSOM 樹。因此辖试,我們需要確保盡快將 HTML 和 CSS 都提供給瀏覽器帅涂。

  • 字節(jié) → 字符 → 令牌 → 節(jié)點 → 對象模型。
  • HTML 標記轉換成文檔對象模型 (DOM)疙咸;CSS 標記轉換成 CSS 對象模型 (CSSOM)县匠。
  • DOM 和 CSSOM 是獨立的數(shù)據(jù)結構。
  • Chrome DevTools Timeline 讓我們可以捕獲和檢查 DOM 和 CSSOM 的構建和處理開銷。

1.1 文檔對象模型 (DOM)

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="style.css" rel="stylesheet">
    <title>Critical Path</title>
  </head>
  <body>
    <p>Hello <span>web performance</span> students!</p>
    <div><img src="awesome-photo.jpg"></div>
  </body>
</html>

讓我們從可能的最簡單情況入手:一個包含一些文本和一幅圖片的普通 HTML 頁面聚唐。瀏覽器如何處理此頁面丐重?


image.png
  1. 轉換: 瀏覽器從磁盤或網(wǎng)絡讀取 HTML 的原始字節(jié),并根據(jù)文件的指定編碼(例如 UTF-8)將它們轉換成各個字符杆查。
  2. 令牌化: 瀏覽器將字符串轉換成 W3C HTML5 標準規(guī)定的各種令牌扮惦,例如,“<html>”亲桦、“<body>”崖蜜,以及其他尖括號內(nèi)的字符串。每個令牌都具有特殊含義和一組規(guī)則客峭。
  3. 詞法分析: 發(fā)出的令牌轉換成定義其屬性和規(guī)則的“對象”豫领。
  4. DOM 構建: 最后,由于 HTML 標記定義不同標記之間的關系(一些標記包含在其他標記內(nèi))舔琅,創(chuàng)建的對象鏈接在一個樹數(shù)據(jù)結構內(nèi)等恐,此結構也會捕獲原始標記中定義的父項-子項關系:HTML 對象是 body 對象的父項,bodyparagraph 對象的父項备蚓,依此類推课蔬。
    整個流程的最終輸出是我們這個簡單頁面的文檔對象模型 (DOM),瀏覽器對頁面進行的所有進一步處理都會用到它郊尝。
    DOM 樹捕獲文檔標記的屬性和關系二跋,但并未告訴我們元素在渲染后呈現(xiàn)的外觀。那是 CSSOM 的責任流昏。

1.2 CSS 對象模型 (CSSOM)

在瀏覽器構建我們這個簡單頁面的 DOM 時扎即,在文檔的 head 部分遇到了一個 link 標記,該標記引用一個外部 CSS 樣式表:style.css况凉。由于預見到需要利用該資源來渲染頁面谚鄙,它會立即發(fā)出對該資源的請求,并返回以下內(nèi)容:

body { font-size: 16px }
p { font-weight: bold }
span { color: red }
p span { display: none }
img { float: right }

與處理 HTML 時一樣茎刚,我們需要將收到的 CSS 規(guī)則轉換成某種瀏覽器能夠理解和處理的東西襟锐。因此撤逢,我們會重復 HTML 過程膛锭,不過是為 CSS 而不是 HTML:


CSS 字節(jié)轉換成字符,接著轉換成令牌和節(jié)點蚊荣,最后鏈接到一個稱為“CSS 對象模型”(CSSOM) 的樹結構內(nèi):

CSSOM 為何具有樹結構初狰?為頁面上的任何對象計算最后一組樣式時,瀏覽器都會先從適用于該節(jié)點的最通用規(guī)則開始(例如互例,如果該節(jié)點是 body 元素的子項奢入,則應用所有 body 樣式),然后通過應用更具體的規(guī)則(即規(guī)則“向下級聯(lián)”)以遞歸方式優(yōu)化計算的樣式媳叨。
以上面的 CSSOM 樹為例進行更具體的闡述腥光。span 標記內(nèi)包含的任何置于 body 元素內(nèi)的文本都將具有 16 像素字號关顷,并且顏色為紅色 — font-size 指令從 body 向下級聯(lián)至 span。不過武福,如果某個 span 標記是某個段落 (p) 標記的子項议双,則其內(nèi)容將不會顯示。
請注意捉片,以上樹并非完整的 CSSOM 樹平痰,它只顯示了我們決定在樣式表中替換的樣式。每個瀏覽器都提供一組默認樣式(也稱為“User Agent 樣式”)伍纫,即我們不提供任何自定義樣式時所看到的樣式宗雇,我們的樣式只是替換這些默認樣式。

2莹规、渲染樹構建赔蒲、布局及繪制

  • DOM 樹與 CSSOM 樹合并后形成渲染樹。
  • 渲染樹只包含渲染網(wǎng)頁所需的節(jié)點良漱。
  • 布局計算每個對象的精確位置和大小嘹履。
  • 最后一步是繪制,使用最終渲染樹將像素渲染到屏幕上债热。

第一步是讓瀏覽器將 DOM 和 CSSOM 合并成一個“渲染樹”砾嫉,網(wǎng)羅網(wǎng)頁上所有可見的 DOM 內(nèi)容,以及每個節(jié)點的所有 CSSOM 樣式信息窒篱。
[圖片上傳失敗...(image-a2ea6d-1545730467906)]
為構建渲染樹焕刮,瀏覽器大體上完成了下列工作:

  1. 從 DOM 樹的根節(jié)點開始遍歷每個可見節(jié)點。
  • 某些節(jié)點不可見(例如腳本標記墙杯、元標記等)配并,因為它們不會體現(xiàn)在渲染輸出中,所以會被忽略高镐。
  • 某些節(jié)點通過 CSS 隱藏溉旋,因此在渲染樹中也會被忽略,例如嫉髓,上例中的 span 節(jié)點---不會出現(xiàn)在渲染樹中观腊,---因為有一個顯式規(guī)則在該節(jié)點上設置了“display: none”屬性。
  1. 對于每個可見節(jié)點算行,為其找到適配的 CSSOM 規(guī)則并應用它們梧油。
  2. 發(fā)射可見節(jié)點,連同其內(nèi)容和計算的樣式州邢。

Note: 簡單提一句儡陨,請注意 visibility: hidden 與 display: none 是不一樣的。前者隱藏元素,但元素仍占據(jù)著布局空間(即將其渲染成一個空框)骗村,而后者 (display: none) 將元素從渲染樹中完全移除嫌褪,元素既不可見,也不是布局的組成部分胚股。

最終輸出的渲染同時包含了屏幕上的所有可見內(nèi)容及其樣式信息渔扎。有了渲染樹,我們就可以進入“布局”階段信轿。
到目前為止晃痴,我們計算了哪些節(jié)點應該是可見的以及它們的計算樣式,但我們尚未計算它們在設備視口內(nèi)的確切位置和大小---這就是“布局”階段财忽,也稱為“自動重排”倘核。
為弄清每個對象在網(wǎng)頁上的確切大小和位置,瀏覽器從渲染樹的根節(jié)點開始進行遍歷即彪。讓我們考慮下面這樣一個簡單的實例:

<!DOCTYPE html>
<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)頁的正文包含兩個嵌套 div:第一個(父)div 將節(jié)點的顯示尺寸設置為視口寬度的 50%紧唱,---父 div 包含的第二個 div---將其寬度設置為其父項的 50%;即視口寬度的 25%隶校。


布局流程的輸出是一個“盒模型”漏益,它會精確地捕獲每個元素在視口內(nèi)的確切位置和尺寸:所有相對測量值都轉換為屏幕上的絕對像素。

最后深胳,既然我們知道了哪些節(jié)點可見绰疤、它們的計算樣式以及幾何信息,我們終于可以將這些信息傳遞給最后一個階段:將渲染樹中的每個節(jié)點轉換成屏幕上的實際像素舞终。這一步通常稱為“繪制”或“柵格化”轻庆。
執(zhí)行渲染樹構建、布局和繪制所需的時間將取決于文檔大小敛劝、應用的樣式余爆,以及運行文檔的設備:文檔越大,瀏覽器需要完成的工作就越多夸盟;樣式越復雜蛾方,繪制需要的時間就越長(例如,單色的繪制開銷“較小”上陕,而陰影的計算和渲染開銷則要“大得多”)桩砰。
最后將在視口中看到網(wǎng)頁。

總結瀏覽器完成的步驟:

  1. 處理 HTML 標記并構建 DOM 樹唆垃。
  2. 處理 CSS 標記并構建 CSSOM 樹五芝。
  3. 將 DOM 與 CSSOM 合并成一個渲染樹。
  4. 根據(jù)渲染樹來布局辕万,以計算每個節(jié)點的幾何信息。
  5. 將各個節(jié)點繪制到屏幕上。

以上流程看起來可能很簡單渐尿,實際上卻需要完成相當多的工作醉途。如果 DOM 或 CSSOM 被修改,您只能再執(zhí)行一遍以上所有步驟砖茸,以確定哪些像素需要在屏幕上進行重新渲染隘擎。
網(wǎng)頁優(yōu)化關鍵渲染路徑 就是指最大限度縮短執(zhí)行上述第 1 步至第 5 步耗費的總時間。 這樣一來凉夯,就能盡快將內(nèi)容渲染到屏幕上货葬,此外還能縮短首次渲染后屏幕刷新的時間,即為交互式內(nèi)容實現(xiàn)更高的刷新率劲够。

tips:為什么將css放在頁面前面引入:
這樣會先加載css的樣式震桶,在渲染dom的時候已經(jīng)知道了自己的樣式了,所以一次渲染成功征绎;
如果css放在底部蹲姐,那么需要先渲染dom,然后加載css后會重新渲染之前dom人柿,需要兩次渲染柴墩。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市凫岖,隨后出現(xiàn)的幾起案子江咳,更是在濱河造成了極大的恐慌,老刑警劉巖哥放,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扎阶,死亡現(xiàn)場離奇詭異,居然都是意外死亡婶芭,警方通過查閱死者的電腦和手機东臀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來犀农,“玉大人惰赋,你說我怎么就攤上這事『巧冢” “怎么了赁濒?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長孟害。 經(jīng)常有香客問我拒炎,道長,這世上最難降的妖魔是什么挨务? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任击你,我火速辦了婚禮玉组,結果婚禮上,老公的妹妹穿的比我還像新娘丁侄。我一直安慰自己惯雳,他們只是感情好,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布鸿摇。 她就那樣靜靜地躺著石景,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拙吉。 梳的紋絲不亂的頭發(fā)上潮孽,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天祖屏,我揣著相機與錄音伴榔,去河邊找鬼肴熏。 笑死菩颖,一個胖子當著我的面吹牛椿访,可吹牛的內(nèi)容都是我干的捷犹。 我是一名探鬼主播乌昔,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼雷逆,長吁一口氣:“原來是場噩夢啊……” “哼名眉!你這毒婦竟也來了粟矿?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤损拢,失蹤者是張志新(化名)和其女友劉穎陌粹,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體福压,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡掏秩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了荆姆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒙幻。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖胆筒,靈堂內(nèi)的尸體忽然破棺而出邮破,到底是詐尸還是另有隱情,我是刑警寧澤仆救,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布抒和,位于F島的核電站,受9級特大地震影響彤蔽,放射性物質(zhì)發(fā)生泄漏摧莽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一顿痪、第九天 我趴在偏房一處隱蔽的房頂上張望镊辕。 院中可真熱鬧油够,春花似錦、人聲如沸丑蛤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽受裹。三九已至,卻和暖如春虏束,著一層夾襖步出監(jiān)牢的瞬間棉饶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工镇匀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留照藻,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓汗侵,卻偏偏與公主長得像幸缕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晰韵,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361