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