本人對瀏覽器的工做原理的理解尚淺,若有錯誤歡迎各位大佬指正。javascript
瀏覽器如何渲染一個頁面css
瀏覽器有哪些線程,線程之間如何工做的html
瞭解瀏覽器渲染原理能夠幫助咱們優化html、css、js的組織,優化渲染性能java
瞭解瀏覽器進程能夠幫助咱們深刻了解異步編程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是指計算每一個DOM元素最終在屏幕上顯示的大小和位置。 遍歷順序爲從左至右,從上到下
因爲web頁面的元素佈局是相對的, 因此任意元素的位置發生變化,都會引發其餘元素位置的變化,這就是reflow
渲染引擎會遍歷渲染樹,由用戶界面後端層將每一個節點繪製出來
按照合理的順序合併圖層而後顯示到屏幕上。
瀏覽器刷新的頻率大概是60次/秒, 也就是說刷新一次大概時間爲16ms
若是瀏覽器對每一幀的渲染工做超過了這個時間, 頁面的渲染就會出現卡頓的現象。
以上過程是漸進的,並不必定嚴格按照順序執行的,爲了更快將內容呈如今不屏幕中, 不會等到HTML所有解析完成以後纔開始構建渲染樹和layout,它會在不斷接收和處理其餘網絡資源的同時,就開始部份內容的解析和渲染
渲染完成以後會觸發 ready事件
當render tree (元素尺寸) 發生變化時則會從新layout 則會所以reflow
用戶界面
瀏覽器內核: 瀏覽器引擎(查詢操做渲染引擎的接口)、渲染引擎、js引擎、網絡(http請求)
數據存儲
js引擎 (IE9+: Chakra firefox:monkey chrome:v8)
渲染引擎(firefox:gecko、chrome/safari:webkit)
因此大部分瀏覽器至少有三個線程:
JS引擎線程、GUI渲染線程、瀏覽器事件觸發線程
除此以外還會有 http請求線程等、計時器線程、EventLoop輪詢的處理線程等。
js引擎是基於事件驅動的, 採用的是單線程運行機制。
由於JS能夠操做DOM元素, 從而影響到GUI的渲染結果, 所以JS引擎線程和GUI渲染線程是互斥的。 也就是說
JS引擎處於運行狀態時,GUI渲染線程將處於凍結狀態。
javascript引擎負責解釋和執行javascript代碼的線程只有一個,稱爲主線程。js還有其餘的線程稱爲工做線程。
主線程上只執行同步任務。
H5提出了Web Worker標準, 容許js建立多個線程, 可是徹底受父線程控制,且不能夠操做DOM
瀏覽器還有還有其餘的線程,例如:
處理 ajax 的線程,dom事件線程、定時器線程、讀寫文件的線程等。這些被稱爲工做進程
這些線程可能存在於js引擎之中或者以外, 稱爲工做線程
工做線程的任務完成以後, 會推入到一個任務隊列(task queue)
js引擎只執行同步任務, 異步任務會有工做線程來執行。
當須要進行異步操做(定時器、ajax請求、dom事件註冊等), 主線程會發一個異步任務的請求, 相應的工做線程接受請求; 當工做線程完成工做以後, 通知主線程;主線程接收到通知以後, 會執行必定的操做(回調函數)。
主線程和工做線程之間的通知機制叫作事件循環。
調用棧 (call stack): 主線程執行時生成的調用棧
任務隊列 (task queue): 工做線程完成任務後會把消息推到一個任務隊列, 消息就是註冊時的回調函數
當調用棧爲空時, 主線程會從任務隊列裏取一條消息並放入當前的調用棧當中執行, 主線程會一直重複這個動做直到消息隊列爲空。 這個過程就叫作事件循環 (event-loop)。
渲染線程和js線程是互斥的, 在js引擎執行時,渲染線程會被掛起。
js在瀏覽器中須要被下載、解釋、執行這三部。 html中的script標籤是阻塞的, 也就是說順序下載、解釋、執行。
瀏覽器會在js執行後決定當前文檔是否須要進行從新渲染或者重排。
js引擎線程和UI線程是互斥的, 因此js執行時會阻塞頁面的渲染。
下載雖然是異步的, 可是執行仍是同步的。 先出現的SCRIPT標籤必定是先執行。 即便它是最後一個下載完成。js執行中終端瀏覽器html解析