首頁>技術>

我們要理解瀏覽器程序和執行緒之間的關係,首先要了解什麼是程序?什麼是執行緒?

程序

程序(Process)是計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位。

示例

開啟谷歌瀏覽器,隨便開啟幾個網頁,按下shift+esc鍵,介面將顯示目前瀏覽器啟動的幾個程序,還有相應的程序記憶體佔用空間、CPU核數、程序ID等等。

在瀏覽器中新開啟一個tab頁,瀏覽器會開啟一個新的程序,但是,這並不意味著,瀏覽器上每一個tab頁就是一個程序,因為

有的頁面是透過連結跳轉開啟的,熟悉前端的朋友知道html裡的a標籤

可以新開一個tab頁,這新開的和原先的屬於同一程序。

瀏覽器程序(Browser程序)

瀏覽器的主程序(負責協調、主控),只有一個。作用有

負責瀏覽器介面顯示,與使用者互動。如前進,後退等 負責各個頁面的管理,建立和銷燬其他程序 將Renderer程序得到的記憶體中的Bitmap,繪製到使用者介面上 網路資源的管理,下載等 GPU程序:

最多一個,用於3D繪製等,可禁止掉。

瀏覽器渲染程序(Renderer程序,內部是多執行緒的)

每一個標籤頁的開啟都會建立一個瀏覽器渲染程序(瀏覽器核心)。預設每個Tab頁面一個程序,互不影響。主要作用為頁面渲染,指令碼執行,事件處理等

執行緒

執行緒(英語:thread)是作業系統能夠進行運算排程的最小單位。它被包含在程序之中,是程序中的實際運作單位。

一條執行緒指的是程序中一個單一順序的控制流,一個程序中可以併發多個執行緒,每條執行緒並行執行不同的任務。

一個程式執行會啟動多個程序,而程序裡又包含了多個執行緒,多個執行緒為程序服務。

下圖為瀏覽器渲染程序中存在的各個執行緒

GUI渲染執行緒

負責渲染瀏覽器介面,解析HTML,CSS,構建DOM樹和RenderObject樹,佈局和繪製等。

當介面需要重繪(Repaint)或由於某種操作引發迴流(reflow)時,該執行緒就會執行

注意,GUI渲染執行緒與JS引擎執行緒是互斥的,當JS引擎執行時GUI執行緒會被掛起(相當於被凍結了),GUI更新會被儲存在一個佇列中等到JS引擎空閒時立即被執行。

JS引擎執行緒

也稱為JS核心,負責處理Javascript指令碼程式。(例如V8引擎)

JS引擎執行緒負責解析Javascript指令碼,執行程式碼。

JS引擎一直等待著任務佇列中任務的到來,然後加以處理,一個Tab頁(renderer程序)中無論什麼時候都只有一個JS執行緒在執行JS程式

同樣注意,GUI渲染執行緒與JS引擎執行緒是互斥的,所以如果JS執行的時間過長,這樣就會造成頁面的渲染不連貫,導致頁面渲染載入阻塞。

事件觸發執行緒

歸屬於瀏覽器而不是JS引擎,用來控制事件迴圈(可以理解,JS引擎自己都忙不過來,需要瀏覽器另開執行緒協助)

當對應的事件符合觸發條件被觸發時,該執行緒會把事件新增到待處理佇列的隊尾,等待JS引擎的處理

注意,由於JS的單執行緒關係,所以這些待處理佇列中的事件都得排隊等待JS引擎處理(當JS引擎空閒時才會去執行)

定時觸發器執行緒

傳說中的setInterval與setTimeout所線上程

瀏覽器定時計數器並不是由JavaScript引擎計數的,(因為JavaScript引擎是單執行緒的, 如果處於阻塞執行緒狀態就會影響記計時的準確)

因此透過單獨執行緒來計時並觸發定時(計時完畢後,新增到事件佇列中,等待JS引擎空閒後執行)

注意,W3C在HTML標準中規定,規定要求setTimeout中低於4ms的時間間隔算為4ms。

非同步http請求執行緒

在XMLHttpRequest在連線後是透過瀏覽器新開一個執行緒請求

將檢測到狀態變更時,如果設定有回撥函式,非同步執行緒就產生狀態變更事件,將這個回撥再放入事件佇列中。再由JavaScript引擎執行。

瀏覽器核心中執行緒之間的關係

GUI渲染執行緒與JS引擎執行緒互斥

因為JS引擎可以修改DOM樹,那麼如果JS引擎在執行修改了DOM結構的同時,

GUI執行緒也在渲染頁面,那麼這樣就會導致渲染執行緒獲取的DOM的元素資訊可能與JS引擎操作DOM後的結果不一致。

為了防止這種現象,GUI執行緒與JS執行緒需要設計為互斥關係,當JS引擎執行的時候,GUI執行緒需要被凍結,

但是GUI的渲染會被儲存在一個隊列當中,等待JS引擎空閒的時候執行渲染。由此也可以推出,

如果JS引擎正在進行CPU密集型計算,那麼JS引擎將會阻塞,長時間不空閒,導致渲染程序一直不能執行渲染,

頁面就會看起來卡頓卡頓的,渲染不連貫,所以,要儘量避免JS執行時間過長。

JS引擎執行緒與事件觸發執行緒、定時觸發器執行緒、非同步HTTP請求執行緒

事件觸發執行緒、定時觸發器執行緒、非同步HTTP請求執行緒三個執行緒有一個共同點,那就是使用回撥函式的形式,

當滿足了特定的條件,這些回撥函式會被執行。這些回撥函式被瀏覽器核心理解成事件,在瀏覽器核心中擁有一個事件佇列,

這三個執行緒當滿足了內部特定的條件,會將這些回撥函式新增到事件佇列中,等待JS引擎空閒執行。例如非同步HTTP請求執行緒,

執行緒如果檢測到請求的狀態變更,如果設定有回撥函式,回撥函式會被新增事件佇列中,等待JS引擎空閒了執行。

但是,JS引擎對事件佇列(宏任務)與JS引擎內的任務(微任務)執行存在著先後循序,當每執行完一個事件佇列的時間,

JS引擎會檢測內部是否有未執行的任務,如果有,將會優先執行(微任務)。

26
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 關於Laravel框架中Guard的底層實現