瀏覽器工作原理學習筆記

瀏覽器工作原理學習筆記

瀏覽器的工作原理:新式網絡瀏覽器幕後揭祕

How Browsers Work: Behind the scenes of modern web browsers

https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/

https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/

Main components

main components

Rendering engine

Gecko(Firefox)

WebKit(Safari,Chrome and Opera)

Rendering engine basic flow

main flow

Parser–Lexer combination

Parsers usually divide the work between two components: the lexer (sometimes called tokenizer) that is responsible for breaking the input into valid tokens, and the parser that is responsible for constructing the parse tree by analyzing the document structure according to the language syntax rules.

Browsers’ error tolerance

You never get an 「Invalid Syntax」 error on an HTML page. Browsers fix any invalid content and go on.

處理腳本和樣式表的順序(需要知道,優化網頁性能的時候用得上

按順序執行,遇到需要網絡請求的腳本,會先完成網絡請求在繼續執行。

腳本標註爲「defer」,就不會停止文檔解析。

HTML5 增加了一個選項,可將腳本標記爲異步,以便由其他線程解析和執行。

WebKit 和 Firefox 都進行了預解析優化,預解析器不會修改 DOM 樹,而是將這項工作交由主解析器處理;預解析器只會解析外部資源(例如外部腳本、樣式表和圖片)的引用。

樣式表:Firefox 在樣式表加載和解析的過程中,會禁止所有腳本。而對於 WebKit 而言,僅當腳本嘗試訪問的樣式屬性可能受尚未加載的樣式表影響時,它纔會禁止該腳本。

The render tree relation to the DOM tree

render tree

圖:「viewport」在WebKit中是「RenderView」對象。

呈現器是和 DOM 元素相對應的,但並非一一對應。非可視化的 DOM 元素不會插入呈現樹中,例如「head」元素。如果元素的 display 屬性值爲「none」,那麼也不會顯示在呈現樹中(但是 visibility 屬性值爲「hidden」的元素仍會顯示)。一個DOM元素也可以對應多個可視化對象,對應多個呈現器。如「select」元素。

樣式計算

構建呈現樹時,需要計算每一個呈現對象的可視化屬性。這是通過計算每個元素的樣式屬性來完成的。

樣式包括來自各種來源的樣式表、inline 樣式元素和 HTML 中的可視化屬性(例如「bgcolor」屬性)。其中後者將經過轉化以匹配 CSS 樣式屬性。

樣式表的來源包括瀏覽器的默認樣式表、由網頁作者提供的樣式表以及由瀏覽器用戶提供的用戶樣式表(瀏覽器允許您定義自己喜歡的樣式。以 Firefox 爲例,用戶可以將自己喜歡的樣式表放在「Firefox Profile」文件夾下)。

Fireafox規則樹

爲了簡化樣式計算,Firefox 還採用了另外兩種樹:規則樹和樣式上下文樹。WebKit 也有樣式對象,但它們不是保存在類似樣式上下文樹這樣的樹結構中,只是由 DOM 節點指向此類對象的相關樣式。

Firefox 規則樹還有助於按照正確的順序應用屬性。

style contexts

樣式表層疊順序

根據 CSS2 規範,層疊的順序爲(優先級從低到高):

  1. 瀏覽器聲明
  2. 用戶普通聲明
  3. 作者普通聲明
  4. 作者重要聲明
  5. 用戶重要聲明
佈局

呈現器在創建完成並添加到呈現樹時,並不包含位置和大小信息。計算這些值的過程稱爲佈局或重排。

HTML 採用基於流的佈局模型,這意味着大多數情況下只要一次遍歷就能計算出幾何信息。處於流中靠後位置元素通常不會影響靠前位置元素的幾何特徵,因此佈局可以按從左至右、從上至下的順序遍歷文檔。但是也有例外情況,比如 HTML 表格的計算就需要不止一次的遍歷。

佈局是一個遞歸的過程。它從根呈現器(對應於 HTML 文檔的 <html> 元素)開始,然後遞歸遍歷部分或所有的框架層次結構,爲每一個需要計算的呈現器計算幾何信息。

Dirty 位系統

爲避免對所有細小更改都進行整體佈局,瀏覽器採用了一種「dirty 位」系統。如果某個呈現器發生了更改,或者將自身及其子代標註爲「dirty」,則需要進行佈局。

有兩種標記:「dirty」和「children are dirty」。「children are dirty」表示儘管呈現器自身沒有變化,但它至少有一個子代需要佈局。

全局佈局和增量佈局

全局佈局是指觸發了整個呈現樹範圍的佈局,觸發原因可能包括:

  1. 影響所有呈現器的全局樣式更改,例如字體大小更改。
  2. 屏幕大小調整。

佈局可以採用增量方式,也就是隻對 dirty 呈現器進行佈局(這樣可能存在需要進行額外佈局的弊端)。
當呈現器爲 dirty 時,會異步觸發增量佈局。例如,當來自網絡的額外內容添加到 DOM 樹之後,新的呈現器附加到了呈現樹中。全局佈局是指觸發了整個呈現樹範圍的佈局,觸發原因可能包括:

異步佈局和同步佈局

增量佈局是異步執行的。全局佈局往往是同步觸發的。

佈局處理

佈局通常具有以下模式:

  1. 父呈現器確定自己的寬度。
  2. 父呈現器依次處理子呈現器,並且:
    1. 放置子呈現器(設置 x,y 座標)。
    2. 如果有必要,調用子呈現器的佈局(如果子呈現器是 dirty 的,或者這是全局佈局,或出於其他某些原因),這會計算子呈現器的高度。
  3. 父呈現器根據子呈現器的累加高度以及邊距和補白的高度來設置自身高度,此值也可供父呈現器的父呈現器使用。
  4. 將其 dirty 位設置爲 false。
全局繪製和增量繪製

和佈局一樣,繪製也分爲全局(繪製整個呈現樹)和增量兩種。

繪製順序

繪製的順序其實就是元素進入堆棧樣式上下文的順序。

CSS2規範定義,塊呈現器的堆棧順序如下:

  1. 背景顏色
  2. 背景圖片
  3. 邊框
  4. 子代
  5. 輪廓
呈現引擎的線程

呈現引擎採用了單線程。幾乎所有操作(除了網絡操作)都是在單線程中進行的。

網絡操作可由多個並行線程執行。並行連接數是有限的。

事件循環

瀏覽器的主線程是事件循環。它是一個無限循環,永遠處於接受處理狀態,並等待事件(如佈局和繪製事件)發生,並進行處理。

CSS2 可視化模型

基礎,這部分多看下原文!!