從程式和執行緒瞭解瀏覽器的工作原理
程式和執行緒
程式(process)和執行緒(thread)是作業系統的基本概念。
現代作業系統都是可以同時執行多個任務的,比如:用瀏覽器上網的同時還可以聽音樂。對於作業系統來說,一個任務就是一個程式,比如開啟一個瀏覽器就是啟動了一個瀏覽器程式,開啟一個 Word 就啟動了一個 Word 程式。
有些程式同時不止做一件事,比如 Word,它同時可以進行打字、拼寫檢查、列印等事情。在一個程式內部,要同時做多件事,就需要同時執行多個“子任務”,我們把程式內的這些“子任務”稱為執行緒。
由於每個程式至少要做一件事,所以一個程式至少有一個執行緒。
系統會給每個程式分配獨立的記憶體,因此程式有它獨立的資源。同一程式內的各個執行緒之間共享該程式的記憶體空間(包括程式碼段,資料集,堆等)。
如果電腦是 windows 系統,開啟工作管理員,可以看到有一個後臺程式列表,在這裡我們可以看到每個程式的記憶體資源資訊以及 CPU 佔有率。
我們再用官方的術語描述一下:
程式是 CPU 資源分配的最小單位(是能擁有資源和獨立執行的最小單位)。
執行緒是 CPU 排程的最小單位(是建立在程式基礎上的一次程式執行單位)。
瀏覽器是多程式的
理解了程式和執行緒之後,接下來我們對瀏覽器進行一定程度上的認識。
瀏覽器是多程式的,每開啟一個 tab 頁,就相當於建立了一個獨立的瀏覽器程式。
圖中開啟了 Chrome 瀏覽器的多個 tab 頁,在 Chrome 工作管理員
中可以看到有多個程式,每一個 tab 頁有一個獨立的程式。
注意:瀏覽器應該也有自己的優化機制,有時候開啟多個 tab 頁,在 Chrome 工作管理員中會看到有些程式被合併了,所以每個 tab 頁對應一個程式並不一定是絕對的。
瀏覽器包含哪些程式?
為了簡化理解,這裡僅列舉主要程式。
-
Browser 程式:瀏覽器的主程式,只有一個。
負責瀏覽器介面的顯示與互動;
各個頁面的管理,建立和銷燬其他程式;
網路的資源管理、下載等。
Renderer 程式:也稱為瀏覽器渲染程式或瀏覽器核心,內部是多執行緒的。主要負責頁面渲染,指令碼執行,事件處理等。
第三方外掛程式:每種型別的外掛對應一個程式,僅當使用該外掛時才建立。
GPU 程式:最多一個,用於 3D 繪製等。
瀏覽器多程式的優勢
由於預設 新開 一個 tab 頁面 新建 一個程式,所以單個 tab 頁面崩潰不會影響到整個瀏覽器;
同樣,第三方外掛崩潰也不會影響到整個瀏覽器;
多程式可以充分利用現代 CPU 多核的優勢;
方便使用沙盒模型隔離外掛等程式,提高瀏覽器的穩定性。
系統為瀏覽器新開的程式分配記憶體、CPU 等資源,所以記憶體和 CPU 的資源消耗也會更大。
瀏覽器核心(渲染程式)
前面說了這麼多的程式,對普通前端操作來說,最重要的還是渲染程式。
瀏覽器的渲染程式是多執行緒的,頁面的渲染,JS的執行,事件的迴圈等,都在這個程式內執行。
渲染程式通常由以下常駐執行緒組成:
1. GUI 渲染執行緒
負責渲染瀏覽器介面,解析 HTML、CSS,構建 DOM tree和 render tree,佈局和繪製等。當介面需要重繪(repaint)或由於某種操作引發迴流(reflow)時,該執行緒就會執行。
2. JS 引擎執行緒
也稱為 JS 核心,負責解析 JavaScript 指令碼,執行程式碼。
-
JavaScript 是單執行緒的。
JavaScript 為什麼是單執行緒的?這與它的用途有關。JavaScript 作為瀏覽器指令碼語言,主要用途是與使用者互動以及操作 DOM。這也決定了它只能是單執行緒的,否則會帶來很複雜的同步問題。想想一下,如果 JavaScript 同時有連個執行緒,一個執行緒在某個 DOM 節點上新增內容,另一個執行緒刪除了這個 DOM 節點,這時瀏覽器應該以哪個執行緒為準呢?所以,為了避免複雜性,JavaScript 從一開始就是單執行緒。
-
GUI 渲染執行緒 與 JS 引擎執行緒是互斥的。
由於 JavaScript 可以操作 DOM,如果在修改元素屬性的同時渲染介面(即 JavaScript 引擎執行緒和 GUI 渲染執行緒同時執行),那麼渲染執行緒前後獲得的元素資料就可能會不一致。因此,為了防止渲染出現不可預期的結果,瀏覽器設定 GUI 渲染執行緒與 JS 引擎為互斥的關係。當 JS 引擎執行時,GUI 執行緒被掛起,GUI 更新被儲存在一個佇列中,等到 JS 引擎執行緒空閒時立即被執行。
-
JS 阻塞頁面載入。
由於 GUI 渲染執行緒與 JS 引擎執行緒是互斥的,當瀏覽器在執行 JavaScript 的時候,GUI 渲染執行緒會被儲存在一個佇列中,直到 JS 程式執行完成,才會接著執行。因此如果 JS 執行時間過長,就會造成頁面的渲染不連貫,導致頁面渲染載入阻塞。
3. 事件觸發執行緒
當一個事件被觸發時,該執行緒會把事件新增到待處理佇列的隊尾,等待 JS 引擎處理。這些事件可以是當前執行的程式碼塊,如定時任務;也可以是來自瀏覽器核心的其他執行緒,如:滑鼠點選、Ajax非同步請求等。但由於 JS 是單執行緒的,這些事件都需要排隊等待 JS 引擎處理。
4. 定時觸發器執行緒
setTimeout
和 setInterval
所在的執行緒。瀏覽器定時計數器並不是由 JS 引擎計數的,因為 JS 是單執行緒的,如果處於阻塞執行緒狀態就會影響計時的準確,所以通過單獨的執行緒來計時並觸發定時更為合理。
5. 非同步 http 請求執行緒
XMLHttpRequest 在建立連線後,通過瀏覽器新開一個執行緒請求,一旦檢測到狀態變更並且設定有回撥函式,非同步執行緒就產生狀態變更事件,將這個回撥再放入事件佇列中,等待 JS 引擎空閒時處理。
Browser 程式和 Renderer 程式的通訊過程
開啟瀏覽器的一個 tab 頁時,我們看下其中的大致過程:
Browser 程式收到使用者請求,通過網路下載獲取頁面內容,然後將該任務通過RendererHost介面傳遞給 Renderer 程式;
-
Renderer 程式的 Renderer 介面收到訊息,簡單解釋後,交給 GUI 渲染執行緒開始渲染;
GUI 渲染執行緒接收請求,載入網頁並渲染網頁,這個過程中可能需要 Browser 程式獲取資源和 GPU 程式來幫助渲染,也可能會有 JS 引擎執行緒操作 DOM(可能造成迴流並重繪);
最後 Renderer 程式將結果傳遞給 Browser 程式;
Browser 程式接收到結果,並將結果繪製出來。
到這裡應該對瀏覽器的運作有一定理解了,我們再來看下瀏覽器是怎麼渲染頁面的。
瀏覽器的渲染流程
瀏覽器核心拿到頁面內容後,渲染過程大概分為以下幾個部分:
- 解析 HTML 檔案,生成 DOM tree;同時解析 CSS 檔案以及樣式元素中的樣式資料,生成 CSS Rules。
- 構建 render tree:根據 DOM tree 和 CSS Rules 來構建 render tree,它可以讓瀏覽器按照正確的順序繪製內容。
- 佈局(layout / reflow):計算各元素尺寸、位置。
- 繪製(paint):繪製頁面畫素資訊。
- 瀏覽器將各層資訊傳送給 GPU,GPU 將各層資訊合成(composite),顯示在螢幕上。
補充:
Webkit 將 render tree 中的元素稱為 render object (或 renderer),每一個 render object 都代表一個的矩形區域,通常對應於相關節點的 CSS 框,這些矩形的排列順序就是它們在螢幕上顯示的順序。
Render object 和 DOM 節點是相對應的,但並非一一對應。非視覺化的 DOM 元素不會插入 render tree 中,例如“head”元素 和 一些 display: none 的節點就沒必要放在 render tree 中了。
這裡只是大致的過程,詳細步驟可以看參考資料中的第一篇。
渲染完成後,接下來就是 JavaScript 邏輯處理了。
參考資料
相關文章
- 瀏覽器執行緒執行順序,瞭解一下瀏覽器執行緒
- 瀏覽器多執行緒和js單執行緒瀏覽器執行緒JS
- 瀏覽器執行緒瀏覽器執行緒
- 瀏覽器渲染程式多執行緒瀏覽器執行緒
- 重學瀏覽器(1)-多程式多執行緒的瀏覽器瀏覽器執行緒
- 瀏覽器執行原理瀏覽器
- 【總結】瀏覽器的執行緒與程式瀏覽器執行緒
- 瞭解 Android 的程式和執行緒Android執行緒
- 從一道執行題,瞭解瀏覽器中JS執行機制瀏覽器JS
- 【瀏覽器】瀏覽器基本工作原理瀏覽器
- 梳理瀏覽器工作原理瀏覽器
- [譯]瀏覽器工作原理探究瀏覽器
- 深入理解瀏覽器工作原理瀏覽器
- 【譯】Go和WebAssembly:在瀏覽器中執行Go程式GoWeb瀏覽器
- 瀏覽器/nodeJS 中的事件環工作原理瀏覽器NodeJS事件
- [譯]從內部瞭解現代瀏覽器(2)瀏覽器
- [譯]從內部瞭解現代瀏覽器(3)瀏覽器
- [譯]從內部瞭解現代瀏覽器(1)瀏覽器
- 瀏覽器執行javaScript程式碼基礎瀏覽器JavaScript
- 一文帶你瞭解執行緒池原理執行緒
- Chrome、Edge瀏覽器內建多執行緒下載Chrome瀏覽器執行緒
- JAVA-快速瞭解執行緒池的基本原理Java執行緒
- 前端效能優化(一)——瀏覽器工作原理前端優化瀏覽器
- python selenium webdriver多執行緒啟動多個瀏覽器PythonWeb執行緒瀏覽器
- java多執行緒程式設計:你真的瞭解執行緒中斷嗎?Java執行緒程式設計
- setTimeout 是到了xx ms 就執行嗎,瞭解瀏覽器的 Event-Loop 機制瀏覽器OOP
- 瀏覽器原理瀏覽器
- 瀏覽器快取你瞭解麼?瀏覽器快取
- 瞭解新版“武漢鏈”瀏覽器瀏覽器
- 從原始碼的角度解析執行緒池執行原理原始碼執行緒
- 從簡單程式碼入手,分析執行緒池原理執行緒
- 透過簡單示例瞭解執行緒池實現原理執行緒
- 瀏覽器工作原理及web 效能優化(上)瀏覽器Web優化
- SpringBoot執行緒池和Java執行緒池的實現原理Spring Boot執行緒Java
- 瀏覽器恢復滾動行為~瞭解一下瀏覽器
- 前端都該懂的瀏覽器工作原理,你懂了嗎?前端瀏覽器
- 前端開發者應該明白的瀏覽器工作原理前端瀏覽器
- 瀏覽器渲染原理瀏覽器