浏览器从输入URL到页面渲染过程 —— 浏览器的进程与线程
之前我有總結(jié)過一篇經(jīng)典面試題:瀏覽器從輸入URL到頁面渲染過程,接下里我將對某些知識點進行更細致的解析。
瀏覽器從輸入URL到頁面渲染過程 系列文章:
(二):瀏覽器從輸入URL到頁面渲染過程 ——頁面渲染流程
——————————————————————————————————————————————————————————
瀏覽器從輸入URL到頁面渲染過程 —— 瀏覽器的進程與線程
我們在使用瀏覽器的過程中,經(jīng)常會為了方便,同時打開好幾個tab頁面,那么這時候 瀏覽器是如何處理這些頁面的呢?(本文以chrome瀏覽器為例說明)
- 打開一個頁面出現(xiàn)五個進程
當我在瀏覽器打開csdn寫文章的tab頁,然后通過的 菜單欄->更多工具->任務管理器 可以看到,瀏覽器為我們開辟了五個進程。
我們僅僅是打開一個標簽頁面,為什么會出現(xiàn)五個進程呢?
進程/線程:一個進程就是一個程序的運行實例——啟動一個程序的時候,操作系統(tǒng)會為該程序創(chuàng)建一塊內(nèi)存,用來存放代碼、運行中的數(shù)據(jù)和一個執(zhí)行任務的主線程,我們把這樣的一個運行環(huán)境叫進程。一個進程可以擁有多個線程,但一個線程只對應一個進程。
我們通過一個例子進行說明:計算 num =(1+2)+(2-3)+(1+3)的值。
首先我們開辟一個進程,用于計算表達式 num =(1+2)+(2-3)+(1+3)的值,具體讓誰來計算呢,當然是進程的小弟(線程)了。進程可以選擇只分配一個小弟(線程)來做這件事情,這個小弟拿到這個任務后,它先計算出 1+2 的值,再計算出 2-3 的值,再計算出1+3的值,最后將這三個值講起來,獲得最終結(jié)果。但是進程發(fā)現(xiàn),如果其中一個步驟出錯了,程序就不會往下進行了,且前面三個步驟沒有必然的聯(lián)系,完全可以派三個小弟(線程)同時來做這件三件事情,最后其中一個小弟負責收尾工作,效率提升的可不止億點點。
當我們打開一個標簽頁時,首先我們需要進行分配資源進行網(wǎng)絡請求,獲取數(shù)據(jù),然后對數(shù)據(jù)進行處理,最后進行頁面渲染工作。因此,我們分別來解讀一下任務管理器中的五個進程:
瀏覽器進程: 主要負責界面顯示、用戶交互、子進程管理,同時提供存儲等功能。
GPU 進程: 其實,Chrome 剛開始發(fā)布的時候是沒有 GPU 進程的。而 GPU 的使用初衷是為了實現(xiàn) 3D CSS 的效果,只是隨后網(wǎng)頁、Chrome 的 UI 界面都選擇采用 GPU 來繪制,這使得 GPU 成為瀏覽器普遍的需求。最后,Chrome 在其多進程架構(gòu)上也引入了 GPU 進程。
網(wǎng)絡進程: 主要負責頁面的網(wǎng)絡資源加載。
渲染進程: 核心任務是將 HTML、CSS 和 JavaScript 轉(zhuǎn)換為用戶可以與之交互的網(wǎng)頁,排版引擎 Blink 和 JavaScript 引擎 V8 都是運行在該進程中,默認情況下,Chrome 會為每個 Tab 標簽創(chuàng)建一個渲染進程。
插件進程(擴展程序): 主要是負責插件的運行,因插件易崩潰,所以需要通過插件進程來隔離,以保證插件進程崩潰不會對瀏覽器和頁面造成影響。
這么做有什么好處呢?
最原始瀏覽器是以單進程為主體思想運行的,當我們打開一個tab頁時,相當于所有的操作只有一個人在做,只有他忙完了所有事情,我們才能看到最終結(jié)果,弊端也很明顯了:
1、不穩(wěn)定性:很多播放器或者動畫需要借助插件得以完成,如果其中一個插件執(zhí)行錯誤了,或者我們的渲染引擎出錯,那整個進程就崩潰掉了。
2、不流暢性:所有頁面的渲染模塊、JavaScript 執(zhí)行環(huán)境以及插件都是運行在同一個線程中的,這就意味著同一時刻只能有一個模塊可以執(zhí)行,如果我們的代碼出現(xiàn)了死循環(huán),拿它就會獨占運行內(nèi)存,導致瀏覽器長時間得不到響應。
3、不安全性:不管是插件還是腳本,他們一旦開始執(zhí)行,就會獲得我們電腦的操作權(quán),那我們的個人信息安全就沒有保證可言了。
所以,發(fā)展到現(xiàn)在,我們的瀏覽器進入了多進程多線程時代:
1、解決不穩(wěn)定性:由于進程是相互隔離的,所以當一個頁面或者插件崩潰時,影響到的僅僅是當前的頁面進程或者插件進程,并不會影響到瀏覽器和其他頁面,這就完美地解決了頁面或者插件的崩潰會導致整個瀏覽器崩潰,也就是不穩(wěn)定的問題。
2、解決不流暢性:JavaScript 也是運行在渲染進程中的,所以即使 JavaScript 阻塞了渲染進程,影響到的也只是當前的渲染頁面,而并不會影響瀏覽器和其他頁面,因為其他頁面的腳本是運行在它們自己的渲染進程中的。所以當我們再在 Chrome 中運行上面那個死循環(huán)的腳本時,沒有響應的僅僅是當前的頁面。
3、解決不安全性:采用多進程架構(gòu)的額外好處是可以使用安全沙箱,你可以把沙箱看成是操作系統(tǒng)給進程上了一把鎖,沙箱里面的程序可以運行,但是不能在你的硬盤上寫入任何數(shù)據(jù),也不能在敏感位置讀取任何數(shù)據(jù),例如你的文檔和桌面。Chrome 把插件進程和渲染進程鎖在沙箱里面,這樣即使在渲染進程或者插件進程里面執(zhí)行了惡意程序,惡意程序也無法突破沙箱去獲取系統(tǒng)權(quán)限。
值得注意的一點就是:雖然一個進程里可以包含多個線程,但是,這要一個線程崩潰了,這個進程就會被卡死了,就和promise.all一樣。但有時我們也會遇到,一個tab頁卡死了,整個瀏覽器都卡住了。那是不是多進程就沒有起到作用呢?其實不是的——通常情況下是一個頁面使用一個進程,但是,有一種情況,叫"同一站點"(根域名 + 協(xié)議),比如:
https://blog.csdn.net
https://www.csdn.net:8888
都是屬于同一站點,因為它們的協(xié)議都是https,而根域名也都是csdn.net。Chrome的默認策略是,每個標簽對應一個渲染進程。但是如果從一個頁面打開了新頁面,而新頁面和當前頁面屬于同一站點時,那么新頁面會復用父頁面的渲染進程。如果幾個頁面符合同一站點,那么他們將被分配到一個渲染進程里面去。所以,這種情況下,一個頁面崩潰了,會導致同一站點的頁面同時崩潰,因為他們使用了同一個渲染進程。
為什么要讓他們跑在一個進程里面呢?
因為在一個渲染進程里面,他們就會共享JS的執(zhí)行環(huán)境,也就是說A頁面可以直接在B頁面中執(zhí)行腳本。
總結(jié)
以上是生活随笔為你收集整理的浏览器从输入URL到页面渲染过程 —— 浏览器的进程与线程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用Jenkins自动化搭建测试环境_入门
- 下一篇: 浏览器从输入URL到页面渲染过程 ——页