Skip to content

瀏覽器的運作原理 ​

瀏覽器是一個用來瀏覽網頁的應用程式,它主要由以下幾個部分組成:

使用者介面 ​

瀏覽器的使用者介面主要由以下幾個部分組成:

  1. 網址列:用來輸入網址,並且前往網頁。
  2. 前進、後退、重新整理、停止:用來控制瀏覽器的前進、後退、重新整理、停止。
  3. 分頁:用來顯示網頁的分頁。
  4. 瀏覽器視窗:用來顯示網頁的內容。

瀏覽器引擎 ​

瀏覽器引擎主要負責解析 HTML、CSS 等資源,並且將這些資源顯示在瀏覽器視窗上。 常見的瀏覽器引擎有:

  1. Blink:Google Chrome 和 Opera 使用的瀏覽器引擎。
  2. WebKit:Safari 使用的瀏覽器引擎。
  3. Gecko:Firefox 使用的瀏覽器引擎。
  4. Trident:Internet Explorer 使用的瀏覽器引擎。
  5. EdgeHTML:Microsoft Edge 使用的瀏覽器引擎。

JavaScript 解析器 ​

上一章我們提到,JavaScript 是直譯讓瀏覽器解析處理的,所以瀏覽器都內建了 JavaScript 解析器。 JavaScript 解析器主要負責解析 JavaScript 語言,並且將這些語言轉換成機器語言,讓電腦可以執行。 常見的 JavaScript 解析器有:

  1. V8:Google Chrome 使用的 JavaScript 解析器。
  2. SpiderMonkey:Firefox 使用的 JavaScript 解析器。
  3. JavaScriptCore:Safari 使用的 JavaScript 解析器。
  4. Chakra:Internet Explorer 使用的 JavaScript 解析器。
  5. ChakraCore:Microsoft Edge 使用的 JavaScript 解析器。

瀏覽器的渲染流程 ​

解析 HTML:建立 DOM 樹 ​

瀏覽器會先將 HTML 解析成 DOM 樹,DOM 樹是一個由節點組成的樹狀結構,每個節點代表了一個 HTML 元素。 比如說:

html
<!DOCTYPE html>
<html>
    <head>
        <title>Document</title>
    </head>
    <body>
        <h1>Hello, World!</h1>
    </body>
</html>

解析後的 DOM 樹會長得像這樣:

html
├── head
│   └── title
│       └── Document
└── body
    └── h1
        └── Hello, World!

解析 CSS,建立 CSSOM 樹 ​

瀏覽器會將 CSS 解析成 CSSOM 樹,CSSOM 樹是一個由節點組成的樹狀結構,每個節點代表了一個 CSS 規則。 比如說:

css
h1 {
    color: red;
}

解析後的 CSSOM 樹會長得像這樣:

h1
└── color: red

接著符合 CSSOM 節點上規則的元素會被標記為 style 屬性,這樣瀏覽器引擎就可以知道該元素的樣式。

合併 DOM 和 CSSOM:瀏覽器引擎會將 DOM 和 CSSOM 合併成一個 Render Tree ​

瀏覽器引擎會將 DOM 和 CSSOM 合併成一個 Render Tree,是一個由節點組成的樹狀結構,每個節點代表了一個可見的元素。 比如說:

html
└── body
    └── h1 (color: red)
        └── Hello, World!

布局 (Layout/Reflow) ​

瀏覽器引擎會計算 Render Tree 的大小和位置,並且決定每個元素在畫面上的位置。 比如說:

// 預設情況下
html (width: 100%, height: 100%)
└── body (width: 100%, height: 100%)
    └── h1 (color: red) (width: 100%, height: 100%, font-size: 16px, line-height: 1.2, color: black, background: transparent)
        └── Hello, World! (width: 100%, height: 100%, font-size: 16px, line-height: 1.2, color: black, background: transparent)

繪製 (Paint) ​

瀏覽器引擎會將 Render Tree 繪製到畫面上,但這還不是最終的畫面,因為接下來要開始執行 JavaScript。

執行 JavaScript ​

瀏覽器引擎會解析 JavaScript,並且執行 JavaScript,這可能會導致 Render Tree 的變化。

比如說,我們將 h1 的顏色改成藍色:

javascript
document.querySelector('h1').style.color = 'blue';

這樣 Render Tree 就會變成:

html
└── body
    └── h1 (color: blue)
        └── Hello, World!

然後由於 Render Tree 的變化,瀏覽器引擎會重新繪製和回流。

重繪和回流(Repaint and Reflow) ​

瀏覽器會監聽 Render Tree 的變化,當 Render Tree 發生變化時,瀏覽器引擎會重新繪製和回流,把畫面上的元素重新計算一次,然後重新繪製到畫面上。

瀏覽器的事件循環:瀏覽器會不斷的執行事件循環,並且處理事件 ​

瀏覽器有一個事件循環機制,瀏覽器會不斷的執行事件循環。 假設有一個按鈕而且我們用滑鼠點了它一下,會產生一個 onClick 事件,這個事件就會被放到事件循環中,等待瀏覽器引擎執行。 假設這個按鈕綁定的事件是改變 h1 的顏色,那麼當事件循環執行到這個事件時,就會改變 h1 的元素,觸發重繪和回流。

結語 ​

重繪跟回流是很重要的 ​

根據以上的流程會發現,一開始瀏覽器會先解析 HTML、CSS,然後建立 DOM、CSSOM,接著合併成 Render Tree。

再經過布局、繪製完成最初的畫面,接著執行 JavaScript。

當 JavaScript 執行第一次時,可能會改變 DOM 導致 Render Tree 的變化,這時瀏覽器會重新繪製和回流。

而且 JavaScript 在綁定事件後,也可能會因為事件的觸發而去變更 DOM 導致 Render Tree 的變化,這時瀏覽器也會重新繪製和回流。

只要改變了 Render Tree,瀏覽器就會重新繪製和回流,這樣的過程會一直持續下去,直到網頁被關閉為止。

但是瀏覽器的繪製是需要時間、需要運算成本的,所以繪製與回流得越多,網頁的效能就會越差。

所以在使用 JavaScript 操作 DOM 時,如何減少繪製與回流就變得非常重要。

為了降低繪製與回流,Virtual DOM 誕生 ​

後來就發展出了 Virtual DOM(即VDOM) 這個概念,透過用 JavaScript 去仿造一個 DOM,有點像是用 VDOM 預演一場戲,然後再去比對 VDOM 跟 DOM 的差異,最後再直接更新這些差異,減少 DOM 迭代的更新次數,進而提升效能。

使用 VDOM 技術來開發的框架有 React, Vue 等等,之後若有機會,會再詳細說明。

Wrirten by Aaron Su