ZLL的每周一更(maybe)--浏览器的运行机制
ZLL的每周一更
- 介紹
- 瀏覽器分類和介紹
- 瀏覽器的結(jié)構(gòu)
- 瀏覽器中的進程和線程
- 瀏覽器解析流程
- 最后
介紹
你好! 這是ZLL每周一更的第一篇內(nèi)容,每周我都會整理關(guān)于前端的一些知識點,幫助大家(以及我自己,^^)在工作以及求職的路上更加順利,這就是這個系列的開篇啦,在開篇的介紹里面肯定不得已要說多一點。好了,來到正題,這周的內(nèi)容是瀏覽器的幕后原理,參考了MDN以及Tali Garsiel && Paul Irish編寫的這篇文章,希望能爭取把知識用更好理解的方式展示給各位,那么就開始啦。
瀏覽器分類和介紹
目前使用的主流瀏覽器有五個:Internet Explorer、Firefox、Safari、Chrome 瀏覽器和 Opera。本文中以開放源代碼瀏覽器為例,即 Firefox、Chrome 瀏覽器和 Safari(部分開源)。根據(jù) StatCounter 瀏覽器統(tǒng)計數(shù)據(jù),目前(2011 年 8 月)Firefox、Safari 和 Chrome 瀏覽器的總市場占有率將近 60%。由此可見,如今開放源代碼瀏覽器在瀏覽器市場中占據(jù)了非常堅實的部分。
瀏覽器的結(jié)構(gòu)
瀏覽器自上至下分為這幾層,分別是
1. 用戶界面 - 包括地址欄、前進/后退按鈕、書簽菜單等。除了瀏覽器主窗口顯示的您請求的頁面外,其他顯示的各個部分都屬于用戶界面。
2. 瀏覽器引擎 - 在用戶界面和呈現(xiàn)引擎之間傳送指令。
3. 呈現(xiàn)引擎 - 負(fù)責(zé)顯示請求的內(nèi)容。如果請求的內(nèi)容是 HTML,它就負(fù)責(zé)解析 HTML 和 CSS 內(nèi)容,并將解析后的內(nèi)容顯示在屏幕上。
4. 網(wǎng)絡(luò) - 用于網(wǎng)絡(luò)調(diào)用,比如 HTTP 請求。其接口與平臺無關(guān),并為所有平臺提供底層實現(xiàn)。
5. 用戶界面后端 - 用于繪制基本的窗口小部件,比如組合框和窗口。其公開了與平臺無關(guān)的通用接口,而在底層使用操作系統(tǒng)的用戶界面方法。
6. JavaScript 解釋器。用于解析和執(zhí)行 JavaScript 代碼。
7. 數(shù)據(jù)存儲。這是持久層。瀏覽器需要在硬盤上保存各種數(shù)據(jù),例如 Cookie。新的 HTML 規(guī)范 (HTML5)定義了“網(wǎng)絡(luò)數(shù)據(jù)庫”,這是一個完整(但是輕便)的瀏覽器內(nèi)數(shù)據(jù)庫。
以上是瀏覽器的主要架構(gòu),但是和我們?nèi)粘g覽器的使用還是有區(qū)別,我們當(dāng)前所用的瀏覽器(例如谷歌)是多進程的,那么以上瀏覽器結(jié)構(gòu)中哪些是需要開啟多進程哪些是只有一個進程處理的呢,首先我們就得來談?wù)?strong>瀏覽器中的進程和線程
瀏覽器中的進程和線程
首先,我們得弄清楚進程和線程的概念
1:進程是一個具有一定獨立功能的程序在一個數(shù)據(jù)集上的一次動態(tài)執(zhí)行的過程,是操作系統(tǒng)進行資源分配和調(diào)度的一個獨立單位
2:線程是擁有資源和獨立運行的最小單位,也是程序執(zhí)行的最小單位
類似于下圖,簡而言之,進程就相當(dāng)于一個工廠,線程就相當(dāng)于工廠中的工人,工廠中的工人(線程)可以共享工廠(進程)中的資源,但是不同工廠(進程)之間不能進行資源共享。
在弄清楚之后,我們就來看看瀏覽器中到底執(zhí)行了哪些進程和哪些線程
瀏覽器中的進程
1:瀏覽器的主進程(負(fù)責(zé)協(xié)調(diào)、主控),只有一個
2:第三方插件進程(每種類型的插件對應(yīng)一個進程,僅當(dāng)使用該插件時才創(chuàng)建)
3:GPU進程(最多一個,用于3D繪制)
4:瀏覽器渲染進程 默認(rèn)每個Tab頁面一個進程,互不影響,控制頁面渲染,腳本執(zhí)行,事件處理等(有時候會優(yōu)化,如多個空白tab會合并成一個進程)
(以下圖片中,用戶界面,瀏覽器引擎,網(wǎng)絡(luò)層,用戶界面后端都屬于瀏覽器主進程)
渲染進程中的線程
基本上分為以下五大線程
1. GUI渲染線程
(GUI渲染進程與上文的GPU進程不是一個…)
- 負(fù)責(zé)渲染瀏覽器界面,解析HTML,CSS,構(gòu)建DOM樹和RenderObject樹,布局和繪制等。
- 當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時,該線程就會執(zhí)行
- 注意,GUI渲染線程與JS引擎線程是互斥的,當(dāng)JS引擎執(zhí)行時GUI線程會被掛起(相當(dāng)于被凍結(jié)了),GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執(zhí)行。
2. JS引擎線程
-
也稱為JS內(nèi)核,負(fù)責(zé)處理Javascript腳本程序。(例如V8引擎)
-
JS引擎線程負(fù)責(zé)解析Javascript腳本,運行代碼。
-
JS引擎一直等待著任務(wù)隊列中任務(wù)的到來,然后加以處理,一個Tab頁(renderer進程)中無論什么時候都只有一個JS線程在運行JS程序
-
同樣注意,GUI渲染線程與JS引擎線程是互斥的,所以如果JS執(zhí)行的時間過長,這樣就會造成頁面的渲染不連貫,導(dǎo)致頁面渲染加載阻塞。
3. 事件線程
-
歸屬于瀏覽器而不是JS引擎,用來控制事件循環(huán)(可以理解,JS引擎自己都忙不過來,需要瀏覽器另開線程協(xié)助)
-
當(dāng)JS引擎執(zhí)行代碼塊如setTimeOut時(也可來自瀏覽器內(nèi)核的其他線程,如鼠標(biāo)點擊、AJAX異步請求等),會將對應(yīng)任務(wù)添加到事件線程中
-
當(dāng)對應(yīng)的事件符合觸發(fā)條件被觸發(fā)時,該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理
-
注意,由于JS的單線程關(guān)系,所以這些待處理隊列中的事件都得排隊等待JS引擎處理(當(dāng)JS引擎空閑時才會去執(zhí)行)
4. 定時器線程
-
傳說中的setInterval與setTimeout所在線程
-
瀏覽器定時計數(shù)器并不是由JavaScript引擎計數(shù)的,(因為JavaScript引擎是單線程的,
如果處于阻塞線程狀態(tài)就會影響記計時的準(zhǔn)確) -
因此通過單獨線程來計時并觸發(fā)定時(計時完畢后,添加到事件隊列中,等待JS引擎空閑后執(zhí)行)
-
注意,W3C在HTML標(biāo)準(zhǔn)中規(guī)定,規(guī)定要求setTimeout中低于4ms的時間間隔算為4ms。
5. 異步HTTP線程
-
在XMLHttpRequest在連接后是通過瀏覽器新開一個線程請求(通過瀏覽器網(wǎng)絡(luò)模塊)
-
將檢測到狀態(tài)變更時,如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個回調(diào)再放入事件隊列中。再由JavaScript引擎執(zhí)行。
瀏覽器解析流程
- 首先,渲染進程通過瀏覽器從網(wǎng)絡(luò)層獲取請求文檔內(nèi)容,然后便開始解析HTML文件,將其中的DOM和CSS文件分別解析成DOM樹和CSS規(guī)則樹,然后共同組成渲染樹,(注意DOM樹與渲染樹的節(jié)點不一定相同,例如display:none的DOM節(jié)點則不會出現(xiàn)在渲染樹中)
- 下一步進入“布局”處理階段,也就是為每個節(jié)點分配一個應(yīng)出現(xiàn)在屏幕上的確切坐標(biāo),也就是我們熟知的重排
- 下一個階段是繪制 - 呈現(xiàn)引擎會遍歷呈現(xiàn)樹,由用戶界面后端層將每個節(jié)點繪制出來,也就是我們熟知的重繪。
所以很容易理解,重排必定會導(dǎo)致重繪,而重繪不會導(dǎo)致重排。
如圖,這是Webkit瀏覽器解析的主流程
在瀏覽器解析的過程中,DOM節(jié)點的解析與CSS節(jié)點的解析是同步進行的,之間并不會阻塞,但是一旦涉及到JS的解析,就會導(dǎo)致阻塞,具體規(guī)則是這樣的:
1:DOM節(jié)點的解析遇到JS時,則會掛起當(dāng)前DOM的解析過程,直到JS請求和執(zhí)行完畢后再繼續(xù)DOM的解析
2:CSS資源的請求解析遇到JS時,則會阻塞當(dāng)前的JS,直到CSS資源加載和構(gòu)建完畢再開始JS的執(zhí)行(CSS構(gòu)建styleSheet的時間非常短,可以忽略不計)
*原因如下:腳本在文檔解析階段會請求樣式信息。如果當(dāng)時還沒有加載和解析樣式,腳本就會獲得錯誤的回復(fù),這樣顯然會產(chǎn)生很多問題。這看上去是一個非典型案例,但事實上非常普遍。Firefox 在樣式表加載和解析的過程中,會禁止所有腳本。而對于 WebKit 而言,僅當(dāng)腳本嘗試訪問的樣式屬性可能受尚未加載的樣式表影響時,它才會禁止該腳本 *
最后
本文只是讓大家對于瀏覽器的運行和解析機制有基本的了解,如果大家想深入了解瀏覽器內(nèi)部的運行機制,且后期可能會根據(jù)自身理解更新已更新內(nèi)容,例如DOM如何解析成DOM樹,瀏覽器解析器的運行規(guī)則,十分推薦大家去閱讀這篇文章,瀏覽器的工作原理,對于文中有錯誤的點也歡迎大家積極指出,咱們下周見!
總結(jié)
以上是生活随笔為你收集整理的ZLL的每周一更(maybe)--浏览器的运行机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: delphi mysql 删除_Delp
- 下一篇: 谷歌浏览器怎么保存网页本身或链接?