瀏覽器工做原理 (一) : 瀏覽器渲染原理 & 瀏覽器內核

瀏覽器工做原理

寫在前面

本人對瀏覽器的工做原理的理解尚淺,若有錯誤歡迎各位大佬指正。javascript

本文章回答了那些問題

  1. 瀏覽器如何渲染一個頁面css

  2. 瀏覽器有哪些線程,線程之間如何工做的html

爲何要學習這些問題

  1. 瞭解瀏覽器渲染原理能夠幫助咱們優化html、css、js的組織,優化渲染性能java

  2. 瞭解瀏覽器進程能夠幫助咱們深刻了解異步編程web

瀏覽器渲染原理

瀏覽器首先下載html、css、js。 接着解析生成dom tree、rule tree和rendering tree。 再經過layout後渲染頁面。ajax

下載

瀏覽器打開頁面以後,會根據頁面URL向服務器發送一個請求,服務器響應頁面的HTML。
(HTML解析過程當中遇到插入的css、和js會同時發起請求資源。)chrome

解析

html/svg 解析生成 dom tree,css 解析生成 css rule tree, 這二者結合生成rendering(render) tree。編程

渲染樹包含多個帶有視覺屬性(顏色、尺寸等)的矩形, 這些矩形的排列順序就是它們在屏幕上的顯示順序後端

解析過程當中遇到js標籤會下載解析執行瀏覽器

解析的過程是詞法分析和語法分析

layout

渲染樹構建完成以後進入layout階段

layout是指計算每一個DOM元素最終在屏幕上顯示的大小和位置。 遍歷順序爲從左至右,從上到下

因爲web頁面的元素佈局是相對的, 因此任意元素的位置發生變化,都會引發其餘元素位置的變化,這就是reflow

paint

渲染引擎會遍歷渲染樹,由用戶界面後端層將每一個節點繪製出來

按照合理的順序合併圖層而後顯示到屏幕上。

瀏覽器刷新的頻率大概是60次/秒, 也就是說刷新一次大概時間爲16ms

若是瀏覽器對每一幀的渲染工做超過了這個時間, 頁面的渲染就會出現卡頓的現象。

以上過程是漸進的,並不必定嚴格按照順序執行的,爲了更快將內容呈如今不屏幕中, 不會等到HTML所有解析完成以後纔開始構建渲染樹和layout,它會在不斷接收和處理其餘網絡資源的同時,就開始部份內容的解析和渲染

渲染完成以後會觸發 ready事件

什麼狀況下會引發 reflow repaint

當render tree (元素尺寸) 發生變化時則會從新layout 則會所以reflow

瀏覽器內核

瀏覽組成

用戶界面

瀏覽器內核: 瀏覽器引擎(查詢操做渲染引擎的接口)、渲染引擎、js引擎、網絡(http請求)

數據存儲

js引擎 (IE9+: Chakra firefox:monkey chrome:v8)

渲染引擎(firefox:gecko、chrome/safari:webkit)

因此大部分瀏覽器至少有三個線程:

JS引擎線程、GUI渲染線程、瀏覽器事件觸發線程

除此以外還會有 http請求線程等、計時器線程、EventLoop輪詢的處理線程等。

javascript引擎

js引擎是基於事件驅動的, 採用的是單線程運行機制。

由於JS能夠操做DOM元素, 從而影響到GUI的渲染結果, 所以JS引擎線程和GUI渲染線程是互斥的。 也就是說
JS引擎處於運行狀態時,GUI渲染線程將處於凍結狀態。

javascript的單線程

javascript引擎負責解釋和執行javascript代碼的線程只有一個,稱爲主線程。js還有其餘的線程稱爲工做線程。

主線程上只執行同步任務。

Web Worker

H5提出了Web Worker標準, 容許js建立多個線程, 可是徹底受父線程控制,且不能夠操做DOM

工做進程

瀏覽器還有還有其餘的線程,例如:

處理 ajax 的線程,dom事件線程、定時器線程、讀寫文件的線程等。這些被稱爲工做進程

這些線程可能存在於js引擎之中或者以外, 稱爲工做線程
工做線程的任務完成以後, 會推入到一個任務隊列(task queue)

JavaScrpt 的異步編程

js引擎只執行同步任務, 異步任務會有工做線程來執行。

異步過程

當須要進行異步操做(定時器、ajax請求、dom事件註冊等), 主線程會發一個異步任務的請求, 相應的工做線程接受請求; 當工做線程完成工做以後, 通知主線程;主線程接收到通知以後, 會執行必定的操做(回調函數)。

事件循環

主線程和工做線程之間的通知機制叫作事件循環。

調用棧 (call stack): 主線程執行時生成的調用棧

任務隊列 (task queue): 工做線程完成任務後會把消息推到一個任務隊列, 消息就是註冊時的回調函數

當調用棧爲空時, 主線程會從任務隊列裏取一條消息並放入當前的調用棧當中執行, 主線程會一直重複這個動做直到消息隊列爲空。 這個過程就叫作事件循環 (event-loop)。

渲染線程和js線程的互斥

渲染線程和js線程是互斥的, 在js引擎執行時,渲染線程會被掛起。

爲何會阻塞

js在瀏覽器中須要被下載、解釋、執行這三部。 html中的script標籤是阻塞的, 也就是說順序下載、解釋、執行。

瀏覽器會在js執行後決定當前文檔是否須要進行從新渲染或者重排。
js引擎線程和UI線程是互斥的, 因此js執行時會阻塞頁面的渲染。

下載雖然是異步的, 可是執行仍是同步的。 先出現的SCRIPT標籤必定是先執行。 即便它是最後一個下載完成。js執行中終端瀏覽器html解析

相關文章
相關標籤/搜索