預(yù)備知識
要想了解瀏覽器架構(gòu)的發(fā)展歷史懊蒸,我們首先需要了解一下進(jìn)程及線程的特性
基礎(chǔ)知識
進(jìn)程可以理解為一個運行中的程序塔嬉,線程則存在于進(jìn)程中蚕甥。
進(jìn)程是系統(tǒng)進(jìn)行資源分配的最小單元搅荞,也就是說阱扬,線程無法單獨的獲取系統(tǒng)的資源,需要使用其所在的進(jìn)程的資源躺彬。
線程由進(jìn)程創(chuàng)建而存在煤墙,當(dāng)進(jìn)程銷毀時,正在運行的線程也會自動銷毀
單線程 vs 多線程
一個進(jìn)程處理任務(wù)時宪拥,可以采用單線程也可以采用多線程仿野,對于多核屬于標(biāo)配的時代,使用多線程處理程序她君,可以極大的提升處理性能
脚作。
比如,我們要計算下面三個表達(dá)式的值缔刹,并顯示出結(jié)果來
A = 1 + 2
B = 20 / 5
C = 7 + 8
console.log(A, B, C)
使用單線程處理時球涛,我們可以把這個過程拆分為四個任務(wù):
- 任務(wù)1 計算 A = 1 + 2
- 任務(wù)2 計算 B = 20 / 5
- 任務(wù)3 計算 C = 7 + 8
- 任務(wù)4 顯示最后的結(jié)果
如果采用多線程,經(jīng)過分析桨螺,我們發(fā)現(xiàn)這四個步驟中宾符,前三個任務(wù)之間是獨立的,可以并行執(zhí)行灭翔,第四個任務(wù)則需要等待前三個任務(wù)結(jié)束后,方能執(zhí)行辣苏。因此我們可以將其分成三個線程來處理肝箱。
三個線程分別處理前三個任務(wù)中的一個,然后選擇一個線程來處理最后一個任務(wù)就好稀蟋。
但是有一點需要注意煌张,只要有一個線程奔潰了,那么整個進(jìn)程都會奔潰退客。
通信
線程間通信
同一個進(jìn)程的線程之間可以共享進(jìn)程的公共數(shù)據(jù)骏融,以便于進(jìn)行讀寫操作链嘀。進(jìn)程通信
對于進(jìn)程間通信,則略為復(fù)雜一些档玻,需要使用IPC
進(jìn)行通信(圖中黑色虛線)怀泊。
要點總結(jié)
從以上的知識點中,提取出對下文有直接影響的幾個點误趴。
1. 進(jìn)程中的任意一個線程出錯霹琼,都會導(dǎo)致整個進(jìn)程的奔潰
2. 線程之間共享進(jìn)程中的數(shù)據(jù)
?3. 當(dāng)一個進(jìn)程關(guān)閉后,操作系統(tǒng)會回首進(jìn)程占用的內(nèi)存
進(jìn)程關(guān)閉后凉当,系統(tǒng)會回收所有的資源枣申,哪怕是由于操作不當(dāng),引起的內(nèi)存泄露問題看杭,內(nèi)存也會被正確回收忠藤。
比如早期的ie瀏覽器,支持很多插件楼雹,而這些插件很容易造成內(nèi)存泄露模孩,這意味著只要瀏覽器開著,內(nèi)存 占用就會越來越多烘豹,所以需要關(guān)閉瀏覽器瓜贾,重新打開,從而讓這些內(nèi)存被回收掉
4. 進(jìn)程之間互相隔離
由于進(jìn)程之間是互相隔離的携悯,從而保證了進(jìn)程的獨立性祭芦。當(dāng)一個進(jìn)程發(fā)生奔潰時,不至于影響其他進(jìn)程憔鬼。進(jìn)程之間需要通信的話龟劲,可以使用IPC技術(shù)
瀏覽器架構(gòu)進(jìn)化史
由于chrome擁有著極大的市場占有率,在多進(jìn)程時代我們將以chrome為案例進(jìn)行解析轴或。
單進(jìn)程時代
故名思義昌跌,單進(jìn)程瀏覽器就是將所有功能都放在一個進(jìn)程中來實現(xiàn)。
在該瀏覽器進(jìn)程中照雁,采用多線程技術(shù)蚕愤,將不同的功能使用不同的線程來實現(xiàn),比如網(wǎng)絡(luò)線程饺蚊、頁面線程等萍诱。
如何多的功能運行在同一個進(jìn)程中,會導(dǎo)致瀏覽器不穩(wěn)定污呼、不流暢裕坊、不安全等問題。
問題1:不穩(wěn)定
瀏覽器中的許多強(qiáng)大功能需要借助于插件來實現(xiàn)燕酷,但是插件是第三方提供的籍凝,非常容易出現(xiàn)問題周瞎。
同時,除去插件容易出現(xiàn)問題饵蒂,頁面線程中的javascript也非常容易出現(xiàn)問題声诸。
從線程和進(jìn)程之間的描述中,可以知道苹享,一個線程的奔潰双絮,會導(dǎo)致整個進(jìn)程的奔潰。
問題2: 不流暢
這個不流暢所指的不僅僅是當(dāng)前頁面的不流暢得问,還有整個瀏覽器的不流暢囤攀。
從上圖中,我們得知宫纬,所有頁面的渲染模塊焚挠,js的執(zhí)行模塊、插件都運行在同一個線程中漓骚,這也就是說蝌衔,同一個時刻只能有一個模塊在執(zhí)行。
比如蝌蹂,下面這個無限循環(huán)的腳本:
function freeze() {
while(true) {
console.log('freeze');
}
}
freeze();
當(dāng)這個腳本執(zhí)行在一個單進(jìn)程的頁面的時候噩斟,由于其是無限循環(huán)的,所以會一直執(zhí)行孤个,從而導(dǎo)致其他模塊沒有機(jī)會執(zhí)行代碼剃允。又因為所有頁面都運行在這個線程中,所以其他頁面也無法執(zhí)行任務(wù)齐鲤,從而導(dǎo)致整個瀏覽器失去相應(yīng)斥废,變卡頓。
問題3:不安全
由于是單進(jìn)程给郊,同時瀏覽器需要系統(tǒng)資源的支持牡肉,比如讀寫cookie等,所以我們無法使用沙箱技術(shù)來進(jìn)行隔離淆九,那么如果是惡意插件和js代碼的話统锤,會引發(fā)安全問題。
插件可以使用C/C++等語言來書寫炭庙,通過插件可以獲取到系統(tǒng)的任意資源跪另,也就意味著該插件可以完全操控電腦。如果是一個惡意插件煤搜,那么它就可以窺探隱私,釋放病毒等唧席,從而引發(fā)安全性問題擦盾。
以上這些就是當(dāng)時瀏覽器的特點嘲驾,不穩(wěn)定,不流暢迹卢,而且不安全辽故。這是一段不堪回首的過去,也許你沒有經(jīng)歷過腐碱,不過你可以想象一下這樣的場景:當(dāng)你正在用瀏覽器打開多個頁面時誊垢,突然某個頁面崩潰了或者失去響應(yīng),隨之而來的是整個瀏覽器的崩潰或者無響應(yīng)症见,然后你發(fā)現(xiàn)你給老板寫的郵件頁面也隨之消失了喂走,這時你的心情會不會和頁面一樣崩潰呢?
多進(jìn)程-早期時代
這是2008年chrome發(fā)布時的進(jìn)程架構(gòu)谋作。
從圖中芋肠,我們可以發(fā)現(xiàn),chrome將渲染模塊和插件模塊單獨封裝到了進(jìn)程中遵蚜,進(jìn)程之間通過IPC進(jìn)行通信帖池。
我們來一一分析一下,它是如何解決單進(jìn)程瀏覽器的三大問題的吭净。
-
不穩(wěn)定問題
插件睡汹、渲染模塊被單獨封裝到了進(jìn)程中,那么當(dāng)一個插件或者一個tab頁面奔潰的時候寂殉,不會影響到其他插件模塊囚巴、渲染模塊,也不會將這個瀏覽器搞到奔潰不撑,從而解決了不穩(wěn)定的問題
-
不流暢問題
同理文兢,由于插件、渲染模塊在主進(jìn)程中的剝離焕檬,那么當(dāng)某一個插件姆坚、頁面發(fā)生阻塞的時候,不會影響到瀏覽器实愚,也不會影響到其他的插件和頁面
-
不安全問題
采用多進(jìn)程后兼呵,我們可以使用沙箱技術(shù)對插件進(jìn)程和渲染進(jìn)程進(jìn)行隔離,這樣即使渲染進(jìn)程或者插件進(jìn)程執(zhí)行了惡意程序腊敲,其也無法獲得系統(tǒng)權(quán)限击喂。
多進(jìn)程-現(xiàn)狀
隨著chrome的發(fā)展,架構(gòu)又有了新的變化碰辅。
chrome進(jìn)一步的將主進(jìn)程中一些服務(wù)進(jìn)行了剝離懂昂,比如網(wǎng)絡(luò)、GPU没宾、AUDIO等凌彬。
這里簡單的對這幾個進(jìn)程進(jìn)行一下介紹
-
瀏覽器主進(jìn)程
- 負(fù)責(zé)界面展示沸柔,與用戶交互。如前進(jìn)铲敛、后退褐澎、書簽等
- 負(fù)責(zé)各個頁面的管理,協(xié)調(diào)各個進(jìn)程
- 伐蒋。工三。。
-
渲染進(jìn)程
負(fù)責(zé)將HTML,CSS,JS轉(zhuǎn)換為網(wǎng)頁先鱼。
排版引擎blink俭正,js引擎V8都是運行在該線程中。
不過凡事都有兩面性型型,雖然多進(jìn)程提升了瀏覽器的穩(wěn)定性段审、安全性、流暢性闹蒜,但是同樣也帶來了一些問題:
更高的資源占用
更復(fù)雜的體系架構(gòu)
瀏覽器各模塊之間耦合性高寺枉、擴(kuò)展性差等問題,會導(dǎo)致現(xiàn)在的架構(gòu)已經(jīng)很難適應(yīng)新的需求了
對于這兩個問題绷落,chrome團(tuán)隊已經(jīng)著手進(jìn)行解決了姥闪,那就是面向服務(wù)架構(gòu)
未來面向服務(wù)的架構(gòu)
chrome整體架構(gòu)采用現(xiàn)代操作系統(tǒng)所采用的面向服務(wù)的架構(gòu)方向發(fā)展,將原來的各種模塊砌烁,抽取筐喳、重構(gòu)成獨立的服務(wù),每個服務(wù)都可以在獨立的進(jìn)程中運行函喉,每個服務(wù)都會提供訪問接口避归,通過IPC來通信,從而構(gòu)建高內(nèi)聚管呵,低耦合梳毙,易于維護(hù)和擴(kuò)展的系統(tǒng)。
chrome最終要把UI捐下,數(shù)據(jù)庫账锹,文件,設(shè)備坷襟,網(wǎng)絡(luò)等模塊重構(gòu)為基礎(chǔ)服務(wù)奸柬,類似于操作系統(tǒng)的底層服務(wù)。
目前chrome正處于老的架構(gòu)向服務(wù)化架構(gòu)過度階段婴程,這將是一個漫長的過程廓奕。
chrome要做的事情,類似于操作系統(tǒng)正在做的事情,我們甚至可以認(rèn)為chrome是一個便攜式操作系統(tǒng)
chrome還提供了彈性方案懂从,當(dāng)運行于資源受限的設(shè)備上的時候授段,會自動將服務(wù)整合到一個進(jìn)程中,從而減輕設(shè)備的壓力番甩。
總結(jié)
本文主要從chrome的角度對瀏覽器的架構(gòu)進(jìn)行了分析。
最初的瀏覽器是單進(jìn)程的届搁,他們不穩(wěn)定缘薛,不流暢,不安全卡睦,之后出現(xiàn)了chrome,創(chuàng)造性的引入了多進(jìn)程架構(gòu)宴胧。隨著chrome應(yīng)用到越來越多的場景,功能也越來越復(fù)雜表锻,原有的架構(gòu)已經(jīng)不能滿足于場景的快速變化恕齐,chrome團(tuán)隊采用了面向服務(wù)架構(gòu)(SOA)進(jìn)行逐步重構(gòu),目前仍然在進(jìn)行中瞬逊。