瀏覽器是我們上網的一個重要工具,是我們重要的信息來源,這里以Chrome瀏覽器為對象,同時作為一名前端工程師,之前對於瀏覽器的認知還不夠深入,所以借着這一系列的文章,進行瀏覽器的逐步分析與學習,加深自己的知識儲備。同時這部分知識也是做頁面性能優化,健康度監控等工具時所必須的基礎知識。
進程和線程
- 進程是系統內存分配的一小部分內存空間
- 進程之間相互獨立(不同進程之間可以相互通信,不過代價很大)
- 進程由單個或多個線程組成
- 多個線程之間是可以相互協作完成工作的
- 同一個進程中各個線程之間共享同一塊內存空間
多進程瀏覽器
chrome瀏覽器使用的是多進程多線程模式,因為現在的網頁復雜性非常高。如果整個瀏覽器是單進程的,有可能某個page界面的拋錯就會導致整個瀏覽器的crash。同時多個界面互相可以訪問相同的內存和相同的執行環境,安全性也是一個大的問題,所以瀏覽器需要采用多進程模式。
瀏覽器的進程大概分為以下這幾種:
- 1,瀏覽器主進程(Browser進程):控制chrome的地址欄,書簽欄,返回和前進按鈕,同時還有瀏覽器的不可見部分,例如網絡請求和文件訪問
- 2,第三方插件進程:每種插件一個進程,插件運行時才會創建
- 3,瀏覽器渲染進程(瀏覽器內核,內部是多線程的):負責界面渲染,腳本執行,事件處理等
- 4,GPU進程:最多一個,用於3D繪制
同時,瀏覽器中的每一個frame框也都是一個獨立的進程,因為瀏覽器的安全策略中,來自不同源的界面,在沒有授權前不可以訪問另一個界面的數據。同時給不同源的界面分配不同的進程可以有效的實現這一效果。
瀏覽器內核
瀏覽器內核是通過取得頁面內容,整理信息,計算和組合最終輸出可視化的圖像結果,通常也被視為瀏覽器渲染進程。Chrome瀏覽器為每個Tab頁面單獨啟用進程,因此每個tab網頁都有其獨立的渲染引擎實例。有些渲染進程會被瀏覽器自己的優化機制進行合並。
瀏覽器內核是多線程的
- GUI線程
負責渲染瀏覽器界面,GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執行,當界面需要重繪或由於某種操作引發的reflow時,該線程就會執行。
- js引擎線程
也稱為JS內核,負責處理JavaScript腳本程序,JS引擎一直等待着任務隊列中任務的到來,然后加以處理,一個Tab頁中無論什么時候都只有一個JS線程在運行JS程序
- 定時觸發器線程 (多個定時器時是否會有多個定時觸發線程)
傳說中的setInterval與setTimeout所在線程, 計數線程,瀏覽器定時計數器並不是由JS引擎計數的。
- 事件觸發線程
屬於瀏覽器而不是JS引擎,當JS引擎執行代碼塊如setTimeOut時(也可來自瀏覽器內核的其他線程,如鼠標點擊、AJAX異步請求等),會將對應任務添加到事件線程中。當對應的事件符合觸發條件被觸發時,該線程會把是事件添加到待處理隊列的隊尾,等待JS引擎的處理。
- 異步http請求線程
XMLHttpRequest在連接后是通過瀏覽器新開的一個線程請求。當檢測到狀態更新時,如果沒有設置回調函數,異步線程就產生狀態 變更事件,將這個回調再放入事件隊列中,等待JS引擎執行。
由於JavaScript是可操縱DOM的,如果在修改這些元素屬性同時渲染界面(即JavaScript線程和UI線程同時運行),那么渲染線程前后獲得的元素數據就可能不一致了。因此為了防止渲染出現不可預期的結果,瀏覽器設置GUI渲染線程與JavaScript引擎為互斥的關系,當JavaScript引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到引擎線程空閑時立即被執行。
瀏覽器內核的主要目標是將html+css+js渲染成開發者預期的UI,
Browser進程和瀏覽器內核通信過程
經過上邊的各個概念的講解,我們已經對瀏覽器是多進程多線程的概念有了大致的認知,下邊我們看下瀏覽器的架構多進程的互相協作,首先引用一張架構圖
每個渲染進程都有一個全局renderprocess對象來管理和主進程的通信並維護全局狀態。瀏覽器為每一個渲染進程都維護一個相應的RenderProcessHost,來管理主進程和渲染進程之間的狀態以及溝通。主進程和渲染進程的通訊使用的是 Chromium的 IPC 系統。
每個渲染進程中,都有一個或多個renderview對象,由RenderProcess來管理,對應於每個tab頁中的內容。RenderProcess負責tab頁中所有發生的事情,其中主線程處理我們發送給用戶的大部分代碼,當然也會有web worker或者service worker處理一部分js代碼。大概的模式可看我們之前介紹的瀏覽器內核。
總結
本片文章大概介紹了下chrome瀏覽器的多進程和多線程架構,同時介紹了該架構的優點以及瀏覽器內核的多線程模型。那么在接下來的一篇中,我們會去詳細的介紹下瀏覽器多進程多線程架構中,不同進程之前的協作方式。
參考引用文章:
https://www.chromium.org/developers/design-documents/multi-process-architecture
https://segmentfault.com/a/1190000012925872
https://developers.google.com/web/updates/2018/09/inside-browser-part1