前言
原文是谷歌上更新的文章懒叛,也參考了國內(nèi)的譯文,做個整理。
國內(nèi)譯文部分出現(xiàn)理解困難時,建議參考原文贰盗,結(jié)合來看。
下面參考有地址
Chrome:架構(gòu)
Chrome正常運行是由多個進程協(xié)同完成的阳欲。
Chrome不僅為每一個標(biāo)簽提供一個進程舵盈,而且現(xiàn)在嘗試為每個站點提供它自己的進程,其中就包括iframe球化。
瀏覽器進程:Browser Process
- 控制程序的“chrome”部分秽晚,包括地址欄、書簽筒愚、后退赴蝇、前進等,還處理Web瀏覽器不可見的巢掺、和特權(quán)部分句伶,如網(wǎng)絡(luò)請求、文件訪問等
渲染進程:Render Process
- 負(fù)責(zé)顯示網(wǎng)站選項卡內(nèi)的所有內(nèi)容
插件進程:Plugin Process
- 控制網(wǎng)站使用的所有插件
GPU進程:GPU Process
- 獨立與其他進程的GPU處理任務(wù)陆淀,被分成多個不同的進程考余,因為GPU處理來自多個程序的請求并將它們繪制在同一個面中
多進程架構(gòu)優(yōu)缺點
優(yōu)點:
- 選項卡的獨立性,可以理解為因為多進程轧苫,從而多選項卡不會因為其中一個選項卡崩潰而導(dǎo)致集體崩潰秃殉。
- 安全性和沙盒,由于操作系統(tǒng)提供了限制進程權(quán)限的方法,因此瀏覽器可以從某些功能中對某些進程進行沙箱處理钾军,如Chrome 限制任意用戶訪問在輸入進程(如渲染進程)下的文件訪問權(quán)限
缺點:
- 耗費內(nèi)存鳄袍,因為進程有自己的私有的內(nèi)存空間,也通常包含公共基礎(chǔ)結(jié)構(gòu)的副本吏恭。
為了節(jié)省內(nèi)存拗小,Chrome限制了可以啟動的進程數(shù)量,限制數(shù)量因設(shè)備的內(nèi)存和CPU功率而異樱哼,但當(dāng)Chrome達(dá)到限制時哀九,它會在一個進程中運行從同一個站點打開的多個選項卡。
Chrome:導(dǎo)航
導(dǎo)航階段-流程示意圖:
導(dǎo)航階段結(jié)束后搅幅,就是文檔加載階段阅束,進入渲染器進程。
Chrome:渲染
渲染器進程負(fù)責(zé)處理選項卡內(nèi)發(fā)生的所有事茄唐,其中主線程處理大部分代碼息裸,排版、柵格線程沪编、work線程也是在渲染器進程中呼盆。
其核心工程就是將HTML、CSS蚁廓、JavaScript轉(zhuǎn)換為用戶使用的網(wǎng)頁访圃。
渲染階段-流程示意圖:
在子資源加載過程中,Chrome會啟用“預(yù)加載掃描器”相嵌,它會檢查HTML中的標(biāo)簽腿时,若存在img、link等標(biāo)簽饭宾,會在瀏覽器進程向網(wǎng)絡(luò)線程發(fā)送請求圈匆。
當(dāng)然JavaScript會阻止DOM的繼續(xù)解析,因為JavaScript代碼中可以使用document.write捏雌,它會改變DOM結(jié)構(gòu)和文檔跃赚,所以默認(rèn)阻塞。如果代碼中無document.write性湿,則可以向script標(biāo)簽添加async或defer屬性纬傲,來進行異步加載和運行JavaScript代碼。
主線程通過遍歷布局樹肤频,生產(chǎn)層樹叹括,然后確定繪制順序,告知合成器線程宵荒。
合成器線程柵格化每個圖層汁雷,并且分成圖塊净嘀,再將圖塊發(fā)送到光柵線程。
光柵線程將圖塊進行格式化并存儲在GPU中侠讯,
然后合成器線程會根據(jù)圖塊信息創(chuàng)建合成幀挖藏,發(fā)送給GPU來顯示。
如果發(fā)生滾動厢漩,合成線程會創(chuàng)建另一個合成幀發(fā)送到GPU膜眠。
合成的好處是,可以在不涉及主線程的情況下(即不涉及樣式計算溜嗜、JavaScript執(zhí)行)就可以完成顯示的操作宵膨。但如果再次發(fā)生了回流、重繪過程炸宵,則一定會涉及主線程辟躏。
Chrome:事件處理
用戶在進行動作交互時
瀏覽器進程先接受到位置,
然后交由渲染器進程進程處理事件
在渲染器進程中土全,當(dāng)合成頁面時捎琐,合成器線程通過將標(biāo)記,將事件處理區(qū)域標(biāo)記為“非快速可滾動區(qū)域”涯曲,以確保可以將該區(qū)域的事件發(fā)送給主線程在塔。如果事件不在該區(qū)域幻件,則合成器線程可以不用等待主線程反饋,進行合成新的合成幀蛔溃。
在程序開發(fā)中绰沥,可以在事件監(jiān)聽器是傳遞passive:true
屬性,來告知瀏覽器贺待,在主線程監(jiān)聽事件同時徽曲,合成器線程也可以繼續(xù)合成新的合成幀。
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault()
}
}, {passive: true});
最小化事件發(fā)送到主線程
因為事件被發(fā)送到主線程會執(zhí)行相應(yīng)的JavaScript代碼麸塞,如果高頻連續(xù)觸發(fā)秃臣,會對性能造成影響。
為了最大限度地減少對主線程的過度調(diào)用哪工,Chrome會合并連續(xù)事件(例如wheel, mousewheel, mousemove, pointermove, touchmove)奥此,并進行延遲調(diào)度,直到下一個 requestAnimationFrame雁比。
當(dāng)然可以在事件中使用getCoalescedEvents方法來獲取有關(guān)這些合并事件的信息稚虎。
window.addEventListener('pointermove', event => {
const events = event.getCoalescedEvents();
for (let event of events) {
const x = event.pageX;
const y = event.pageY;
// draw a line using x and y coordinates.
}
});
但任何離散事件,例如 keydown偎捎、 keyup蠢终、 mouseup序攘、 mousedown、 touchstart寻拂、和 touchend 都會被立即發(fā)送程奠。
參考
Chromium_doc_zh
原文:
Inside look at modern web browser (part 1)
Inside look at modern web browser (part 4)
Inside look at modern web browser (part 4)
Inside look at modern web browser (part 4)
譯文:
現(xiàn)代瀏覽器探秘(part 1):架構(gòu)
現(xiàn)代瀏覽器探秘(part2):導(dǎo)航
現(xiàn)代瀏覽器探秘(part3):渲染
現(xiàn)代瀏覽器探秘(part4):事件處理