摘要:瀏覽器的渲染進程是多線程的。因此為了防止渲染出現不可預期的結果,瀏覽器設置渲染線程與引擎為互斥的關系,當引擎執行時線程會被掛起,更新則會被保存在一個隊列中等到引擎線程空閑時立即被執行。
本篇文章參考自撒網要見魚大佬的 僅供自己學習提升。
https://segmentfault.com/a/11...
區分線程和進程**- 什么是進程** 狹義定義:進程是正在運行的程序的實例(an instance of a computer program that is being executed)。 廣義定義:進程是一個具有一定獨立功能的程序關于某個數據集合的一次運行活動。它是操作系統動態執行的基本單元,在傳統的操作系統中,進程既是基本的分配單元,也是基本的執行單元。 **- 什么是線程** 線程(英語:thread)是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以并發多個線程,每條線程并行執行不同的任務。
在當代面向線程設計的計算機結構中,進程是線程的容器。
先看個形象的比喻:
- 進程是一個工廠,工廠有它的獨立資源 - 工廠之間相互獨立 - 線程是工廠中的工人,多個工人協作完成任務 - 工廠內有一個或多個工人 - 工人之間共享空間
再完善完善概念:
- 工廠的資源 -> 系統分配的內存(獨立的一塊內存) - 工廠之間的相互獨立 -> 進程之間相互獨立 - 多個工人協作完成任務 -> 多個線程在進程中協作完成任務 - 工廠內有一個或多個工人 -> 一個進程由一個或多個線程組成 - 工人之間共享空間 -> 同一進程下的各個線程之間共享程序的內存空間(包括代碼段、數據集、堆等)
然后再鞏固下:
可以打開任務管理器,可以看到有一個后臺進程列表。這里就是查看進程的地方,而且可以看到每個進程的內存資源信息以及cpu占有率。
瀏覽器是多線程的理解了進程與線程了區別后,接下來對瀏覽器進行一定程度上的認識:(先看下簡化理解)
瀏覽器是多進程的
瀏覽器之所以能夠運行,是因為系統給它的進程分配了資源(cpu、內存)
簡單點理解,每打開一個Tab頁,就相當于創建了一個獨立的瀏覽器進程。
圖中打開了Chrome瀏覽器的多個標簽頁,然后可以在Chrome的任務管理器中看到有多個進程(分別是每一個Tab頁面有一個獨立的進程,以及一個主進程)。
注意:在這里瀏覽器應該也有自己的優化機制,有時候打開多個tab頁后,可以在Chrome任務管理器中看到,有些進程被合并了
瀏覽器都包含哪些進程?主要包含哪些進程:(為了簡化理解,僅列舉主要進程)
Browser進程:瀏覽器的主進程(負責協調、主控),只有一個。作用有
負責瀏覽器界面顯示,與用戶交互。如前進,后退等
負責各個頁面的管理,創建和銷毀其他進程
將Renderer進程得到的內存中的Bitmap,繪制到用戶界面上
網絡資源的管理,下載等
第三方插件進程:每種類型的插件對應一個進程,僅當使用該插件時才創建
GPU進程:最多一個,用于3D繪制等
瀏覽器渲染進程(瀏覽器內核)(Renderer進程,內部是多線程的):默認每個Tab頁面一個進程,互不影響。主要作用為
頁面渲染,腳本執行,事件處理等
強化記憶:在瀏覽器中打開一個網頁相當于新起了一個進程(進程內有自己的多線程)
瀏覽器多進程的優勢相比于單進程瀏覽器,多進程有如下優點:
避免單個page crash影響整個瀏覽器
避免第三方插件crash影響整個瀏覽器
多進程充分利用多核優勢
方便使用沙盒模型隔離插件等進程,提高瀏覽器穩定性
簡單點理解:如果瀏覽器是單進程,那么某個Tab頁崩潰了,就影響了整個瀏覽器,體驗有多差;同理如果是單進程,插件崩潰了也會影響整個瀏覽器;
重點是瀏覽器內核(渲染進程)對于普通的前端操作來說,頁面的渲染,JS的執行,事件的循環,都在這個進程內進行。瀏覽器的渲染進程是多線程的。
渲染進程包含哪些主要的線程?
1.GUI渲染線程【圖形用戶界面(Graphical User Interface,簡稱 GUI,又稱圖形用戶接口)】
負責渲染瀏覽器界面,解析HTML,CSS,構建DOM樹和RenderObject樹,布局和繪制等。
當界面需要重繪(Repaint)或由于某種操作引發回流(reflow)時,該線程就會執行
注意,GUI渲染線程與JS引擎線程是互斥的,當JS引擎執行時GUI線程會被掛起(相當于被凍結了),GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執行。
2.JS引擎線程
也稱為JS內核,負責處理Javascript腳本程序。(例如V8引擎)
JS引擎線程負責解析Javascript腳本,運行代碼。
JS引擎一直等待著任務隊列中任務的到來,然后加以處理,一個Tab頁(renderer進程)中無論什么時候都只有一個JS線程在運行JS程序
同樣注意,GUI渲染線程與JS引擎線程是互斥的,所以如果JS執行的時間過長,這樣就會造成頁面的渲染不連貫,導致頁面渲染加載阻塞。
3.事件觸發線程
歸屬于瀏覽器而不是JS引擎,用來控制事件循環(可以理解,JS引擎自己都忙不過來,需要瀏覽器另開線程協助)
當JS引擎執行代碼塊如setTimeOut時(也可來自瀏覽器內核的其他線程,如鼠標點擊、AJAX異步請求等),會將對應任務添加到事件線程中
當對應的事件符合觸發條件被觸發時,該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理(事件循環 Event Loop)
注意,由于JS的單線程關系,所以這些待處理隊列中的事件都得排隊等待JS引擎處理(當JS引擎空閑時才會去執行)
4.定時觸發器線程
傳說中的setInterval與setTimeout所在線程
瀏覽器定時計數器并不是由JavaScript引擎計數的,(因為JavaScript引擎是單線程的, 如果處于阻塞線程狀態就會影響記計時的準確)
因此通過多帶帶線程來計時并觸發定時【計時完畢后,添加到事件隊列中,等待JS引擎空閑后執行,這也是“JavaScript定時器不準確”的原因(可用requestAnimationFrame)】
注意,W3C在HTML標準中規定,規定要求setTimeout中低于4ms的時間間隔算為4ms。
5.異步http請求線程
在XMLHttpRequest在連接后是通過瀏覽器新開一個線程請求
將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件隊列中。再由JavaScript引擎執行。
為什么JS引擎是單線程的?為什么需要異步? 單線程又是如何實現異步的呢? 查看【鏈接描述】
Browser進程和瀏覽器內核(Renderer進程)的通信過程如果自己打開任務管理器,然后打開一個瀏覽器,就可以看到:任務管理器中出現了兩個進程(一個是主控進程,一個則是打開Tab頁的渲染進程),
然后在這前提下,看下整個的過程:(簡化了很多)
Browser進程收到用戶請求,首先需要獲取頁面內容(譬如通過網絡下載資源),隨后將該任務通過RendererHost接口傳遞給Render進程
Renderer進程的Renderer接口收到消息,簡單解釋后,交給渲染線程,然后開始渲染
渲染線程接收請求,加載網頁并渲染網頁,這其中可能需要Browser進程獲取資源和需要GPU進程來幫助渲染
當然可能會有JS線程操作DOM(這樣可能會造成回流并重繪)
最后Render進程將結果傳遞給Browser進程
Browser進程接收到結果并將結果繪制出來
這里繪一張簡單的圖:(很簡化)
梳理瀏覽器內核中線程之間的關系GUI渲染線程與JS引擎線程互斥
由于JavaScript是可操縱DOM的,如果在修改這些元素屬性同時渲染界面(即JS線程和UI線程同時運行),那么渲染線程前后獲得的元素數據就可能不一致了。
因此為了防止渲染出現不可預期的結果,瀏覽器設置GUI渲染線程與JS引擎為互斥的關系,當JS引擎執行時GUI線程會被掛起,
GUI更新則會被保存在一個隊列中等到JS引擎線程空閑時立即被執行。
從上述的互斥關系,可以推導出,JS如果執行時間過長就會阻塞頁面。
譬如,假設JS引擎正在進行巨量的計算,此時就算GUI有更新,也會被保存到隊列中,等待JS引擎空閑后執行。
然后,由于巨量計算,所以JS引擎很可能很久很久后才能空閑,自然會感覺到巨卡無比。
所以,要盡量避免JS執行時間過長,這樣就會造成頁面的渲染不連貫,導致頁面渲染加載阻塞的感覺。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102355.html
摘要:腳本執行,事件處理等。引擎線程,也稱為內核,負責處理腳本程序,例如引擎。事件觸發線程,用來控制事件循環可以理解為,引擎線程自己都忙不過來,需要瀏覽器另開線程協助。異步請求線程,也就是發出請求后,接收響應檢測狀態變更等都是這個線程管理的。 一、進程與線程 現代操作系統比如Mac OS X,UNIX,Linux,Windows等,都是支持多任務的操作系統。 什么叫多任務呢?簡單地說,就是操...
摘要:的單線程,與它的用途有關。為了利用多核的計算能力,提出標準,允許腳本創建多個線程,但是子線程完全受主線程控制,且不得操作。 showImg(https://segmentfault.com/img/remote/1460000016649971?w=1481&h=876); 一、進程與線程 1.進程 進程是指程序的一次執行,它占有一片獨有的內存空間,可以通過windows任務管理器查看...
摘要:的單線程,與它的用途有關。為了利用多核的計算能力,提出標準,允許腳本創建多個線程,但是子線程完全受主線程控制,且不得操作。 showImg(https://segmentfault.com/img/remote/1460000016649971?w=1481&h=876); 一、進程與線程 1.進程 進程是指程序的一次執行,它占有一片獨有的內存空間,可以通過windows任務管理器查看...
摘要:的單線程,與它的用途有關。為了利用多核的計算能力,提出標準,允許腳本創建多個線程,但是子線程完全受主線程控制,且不得操作。 showImg(https://segmentfault.com/img/remote/1460000016649971?w=1481&h=876); 一、進程與線程 1.進程 進程是指程序的一次執行,它占有一片獨有的內存空間,可以通過windows任務管理器查看...
摘要:的單線程,與它的用途有關。為了利用多核的計算能力,提出標準,允許腳本創建多個線程,但是子線程完全受主線程控制,且不得操作。 showImg(https://segmentfault.com/img/remote/1460000016649971?w=1481&h=876); 一、進程與線程 1.進程 進程是指程序的一次執行,它占有一片獨有的內存空間,可以通過windows任務管理器查看...
閱讀 1641·2019-08-30 15:44
閱讀 2565·2019-08-30 11:19
閱讀 393·2019-08-30 11:06
閱讀 1556·2019-08-29 15:27
閱讀 3077·2019-08-29 13:44
閱讀 1621·2019-08-28 18:28
閱讀 2352·2019-08-28 18:17
閱讀 1977·2019-08-26 10:41