摘要:瀏覽器顯示及交互背后的原理引子因為筆者愛編程的光頭強近期在寫一本關(guān)于小程序入門的書籍。不基于瀏覽器背后的運行原理,是很難說清楚虛擬被引入的真正原因和最大好處的。它是瀏覽器的核心部分。
瀏覽器顯示及交互背后的原理 引子
因為筆者(愛編程的光頭強)近期在寫一本關(guān)于小程序入門的書籍。其中有一章是介紹虛擬DOM的,它是位于Javascript和真正DOM之間的一層緩存層。為什么引入它,為什么它這么流行,前端三大框架,小程序等,隨處可見它的身影。其背后原理是什么。不基于瀏覽器背后的運行原理,是很難說清楚虛擬DOM被引入的真正原因和最大好處的。為了弄清楚瀏覽器背后運行的邏輯,我查了大量資料,不得不吐槽一下,互聯(lián)網(wǎng)知識盡管多,魚龍混雜、參差不齊、錯漏百出,基本是常態(tài),能找到一篇含金量十分高的文章是不容易的。很幸運,關(guān)于這個問題,我還真找到了一篇,本文就是對它的解讀。好記性不如爛筆頭。
注:本文所有網(wǎng)址都是經(jīng)過百度短網(wǎng)址處理過的,便于排版及美觀。
原文引用https://dwz.cn/iv59xbaG 《前端文摘:深入解析瀏覽器的幕后工作原理》
https://dwz.cn/b72rXXOy 《瀏覽器的工作原理:新式網(wǎng)絡(luò)瀏覽器幕后揭秘》
https://dwz.cn/tn00LUqY 《How browsers work-Behind the scenes of modern web browsers》
https://dwz.cn/bb84qh4a 《HTMLLiving Standard — Last Updated 9 August 2019》
https://drafts.csswg.org/cssom/ 《CSS Object Model (CSSOM)》
https://www.w3.org/TR/css3-co...《CSS Conditional Rules Module Level 3》
https://fetch.spec.whatwg.org/ 《Fetch Living Standard — Last Updated 9 August 2019》
https://dom.spec.whatwg.org/《DOM Living Standard — Last Updated 9 August 2019》
http://t.cn/AiTQEiZr《Explore the Magic Behind Google Chrome》
https://dwz.cn/LtqlF3Qn 《The Security Architecture of the Chromium Browser》
https://dwz.cn/hfEtd7H7 《Chromium的Render進(jìn)程啟動過程分析》
https://dwz.cn/siobBJ1k 《排版引擎》
正文本文相當(dāng)于一篇讀書筆記,我們按照原文順序來一點點深入。
瀏覽器市場份額占比:
Chrome
63.34%
Safari
15.06%
Firefox
4.48%
Samsung Internet
3.77%
UC Browser
3.58%
Opera
2.58%
從以上瀏覽器份額,可以看出,chrome占絕對比,所以我們的測試就基于它。
引擎的通俗解釋就是驅(qū)動器、發(fā)動機(jī),在軟件中是以一套組件或者擴(kuò)展程序、包存在的核心代碼,相當(dāng)于計算機(jī)的CPU。Wikipedia的解釋是瀏覽器引擎即布局引擎,排版引擎,渲染引擎等。Chrome、Safari使用的是Webkit引擎,Mozilla使用的是Gecho引擎,有時候也叫內(nèi)核。參考:Https://Dwz.Cn/Tr3rrt8m
以上定義對大眾是足夠的,但對于想搞清楚瀏覽器運行機(jī)制的人來說,不夠。很顯然,它籠統(tǒng)的將瀏覽器幾塊核心程序(引擎)統(tǒng)稱為一個了,并使用其中一個作為全部核心的代稱,這很容易讓人混淆。
果然,stackoverflow就有人提到了這樣的混淆(https://dwz.cn/7ccPJcX6), 本文引用的以色列那位女工程師文章中,將瀏覽器組件分為了7個,用戶界面(UI),瀏覽器引擎,呈現(xiàn)引擎,網(wǎng)絡(luò),用戶界面后端,JavaScript 解釋器,數(shù)據(jù)存儲等。
這里的瀏覽器引擎到底指什么呢,很顯然它并不是wikipedia里的大眾解釋,stackoverflow有個答案我覺得比較靠譜,它的解釋基于chrome瀏覽器的多進(jìn)程架構(gòu),筆者(愛編程的光頭強)使用chrome自帶的中文翻譯,翻譯了這段,供大家參考:
我不知道如何用“引擎”來解釋。讓我通過在具有多進(jìn)程架構(gòu)的chrome瀏覽器的上下文中使用的“【瀏覽器主進(jìn)程:管理渲染器進(jìn)程的主瀏覽器進(jìn)程。
渲染器進(jìn)程:基本上可理解為一個標(biāo)簽卡(chrome)。可能因為惡意Web內(nèi)容,導(dǎo)致整個瀏覽器崩潰或危及宿主機(jī)系統(tǒng),為了防止這種情況發(fā)生,瀏覽器進(jìn)程委托多帶帶的渲染進(jìn)程(Renderer進(jìn)程(選項卡進(jìn)程))處理每個請求的Web內(nèi)容,它沒有用戶權(quán)限(即對OS系統(tǒng)調(diào)用的訪問權(quán)限有限)。
當(dāng)請求網(wǎng)站時,渲染進(jìn)程將請求轉(zhuǎn)發(fā)到瀏覽器進(jìn)程,進(jìn)而發(fā)起對導(dǎo)航網(wǎng)站的網(wǎng)絡(luò)請求。在Web內(nèi)容到達(dá)之后,瀏覽器進(jìn)程將內(nèi)容發(fā)送回渲染進(jìn)程。渲染器進(jìn)程解析HTML,CSS文件,準(zhǔn)備DOM,CSSOM,維護(hù)JS運行時(V8實例)并將內(nèi)容作為位圖格式發(fā)送到瀏覽器進(jìn)程以在UI上顯示它。
瀏覽器進(jìn)程將渲染器進(jìn)程視為黑盒子,期望渲染器進(jìn)程將某種格式的Web內(nèi)容轉(zhuǎn)換為所需格式,其中包括幾個子組件,布局引擎(進(jìn)程,layout(chrome)/reflow(mozilla)是其中一個。
因此,瀏覽器進(jìn)程處理用戶特權(quán)資源/請求,例如訪問文件系統(tǒng),網(wǎng)絡(luò)等,其中沙盒渲染器進(jìn)程負(fù)責(zé)將網(wǎng)頁轉(zhuǎn)換為瀏覽器進(jìn)程可以將其顯示在OS窗口管理器中的格式。
這其中涉及到兩個概念,一個是瀏覽器進(jìn)程,一個是渲染進(jìn)程。
我認(rèn)為答案取決于我們在這里討論的背景。二、渲染引擎(呈現(xiàn)引擎)背景1:如果你正在和一個只知道網(wǎng)絡(luò)基本知識的朋友交談......
此上下文中的瀏覽器引擎是指為您的瀏覽器提供內(nèi)容并負(fù)責(zé)在屏幕上顯示內(nèi)容的軟件。如果您在維基百科中搜索瀏覽器引擎,它會告訴您流行的瀏覽器引擎包括Webkit,Gecko,Trident等(https://en.wikipedia.org/wiki...)。
在這種情況下,估計很少有人知道有渲染引擎這個東西存在。
背景2:如果你正在和知道瀏覽器如何工作的朋友以及他們背后的所有瘋狂魔法交談......
此上下文中的瀏覽器引擎是指瀏覽器進(jìn)程,主要負(fù)責(zé)管理所有I/o進(jìn)程和顯示UI及跟渲染引擎通信等。
瀏覽器引擎:在UI和渲染引擎之間編組操作。
這也是正確的。如果你看一下Chromium的架構(gòu),你會發(fā)現(xiàn)瀏覽器進(jìn)程/引擎使用渲染進(jìn)程來協(xié)調(diào)頁面內(nèi)容。
此上下文中的渲染引擎是指構(gòu)造DOM,執(zhí)行JavaScript和布局網(wǎng)頁的程序,例如Webkit,Gecko,Trident。渲染引擎由兩個主要組件組成:WebCore包含核心布局功能,JavaScriptCore包含JavaScript解釋器V8。
您的朋友似乎是專家,還必須了解渲染過程,該過程負(fù)責(zé)構(gòu)建網(wǎng)頁。渲染引擎只是渲染過程中的關(guān)鍵部分。
下圖顯示了Chromium體系結(jié)構(gòu)的高級體系結(jié)構(gòu)概述(Google Chrome開源版本)。如果您想了解更多有關(guān)現(xiàn)代瀏覽器背后的魔力的信息,可以查看以下文章:https://medium.com/@zicodeng/...
對文檔或其他資源進(jìn)行解析后,渲染到瀏覽器窗口顯示。它是瀏覽器的核心部分。通常包含dom解析,css解析,生成render樹,layout/reflow,repaint,直至呈現(xiàn)給用戶。
三、內(nèi)容8000個chunck(塊)文中提到“內(nèi)容的大小一般限制在 8000 個chunck塊以內(nèi)”,解釋:Web服務(wù)器生成HTTP Response時無法在Header就確定消息大小的,這時一般來說服務(wù)器將不會提供Content-Length的頭信息,而采用Chunked編碼動態(tài)的提供body內(nèi)容的長度。進(jìn)行Chunked編碼傳輸?shù)腍TTP Response會在消息頭部設(shè)置:
Transfer-Encoding: chunked
瀏覽器請求到HTML代碼后,在生成DOM的開始階段,并行發(fā)起css、圖片、js的請求。CSS文件下載完成后開始構(gòu)建CSSOM。CSSOM構(gòu)建完成后和DOM合并生成Render Tree(attachment)。瀏覽器計算出每個節(jié)點在屏幕的位置進(jìn)行布局。布局完成后,通過顯卡,將內(nèi)容畫到屏幕上。JS修改了DOM或者CSS屬性后,Layout和Paint也會被重復(fù)執(zhí)行。圖片下載完成后也需要調(diào)用Layout和Paint來更新網(wǎng)頁。
五、dom+cssom -> render tree從dom,cssom到渲染樹(frame樹)的過程不同的內(nèi)核樹的概念不太一樣的,不過所做的工作都大同小異,就是計算形成若干能用于布局的矩形盒子(寬度、高度和位置等幾何信息,該計算過程具體實現(xiàn)在layout或reflow階段),box模型。
Gecko 將視覺格式化元素組成的樹稱為“框架樹”。每個元素都是一個框架。WebKit 使用的術(shù)語是“呈現(xiàn)樹”,它由“呈現(xiàn)對象”組成。對于元素的放置,WebKit 使用的術(shù)語是“布局”,而 Gecko 稱之為“重排”。對于連接 DOM 節(jié)點和可視化信息從而創(chuàng)建呈現(xiàn)樹的過程,WebKit 使用的術(shù)語是“附加”。有一個細(xì)微的非語義差別,就是 Gecko 在 HTML 與 DOM 樹之間還有一個稱為“內(nèi)容槽”的層,用于生成 DOM 元素。
六、樹及DOM節(jié)點樹包含 DOM 節(jié)點,指的樹是由實現(xiàn)了某些DOM 接口的元素構(gòu)成的。每個元素都有一條原型鏈,標(biāo)準(zhǔn)定義了每個DOM節(jié)點或元素必須要實現(xiàn)的DOM接口(屬性,方法,事件)。
七、添加defer,async的腳本預(yù)解析通常html被解析的時候遇到j(luò)s會阻塞執(zhí)行,為了優(yōu)化體驗和速度,采用延遲或異步的方式,此時就存在了資源的預(yù)解析或異步執(zhí)行的過程了。
八、共享樣式共享樣式數(shù)據(jù)
WebKit 節(jié)點會引用樣式對象 (RenderStyle)。這些對象在某些情況下可以由不同節(jié)點共享。這些節(jié)點是同級關(guān)系,并且:
這些元素必須處于相同的鼠標(biāo)狀態(tài)(例如,不允許其中一個是“:hover”狀態(tài),而另一個不是)
任何元素都沒有 ID
標(biāo)記名稱應(yīng)匹配
類屬性應(yīng)匹配
映射屬性的集合必須是完全相同的
鏈接狀態(tài)必須匹配
焦點狀態(tài)必須匹配
任何元素都不應(yīng)受屬性選擇器的影響,這里所說的“影響”是指在選擇器中的任何位置有任何使用了屬性選擇器的選擇器匹配
元素中不能有任何 inline 樣式屬性
不能使用任何同級選擇器。WebCore 在遇到任何同級選擇器時,只會引發(fā)一個全局開關(guān),并停用整個文檔的樣式共享(如果存在)。這包括 + 選擇器以及 :first-child 和 :last-child 等選擇器。
代碼:
- 11
- 22
- 33
div ul li{ color: red; width: 100px; height: 36px; }
以上代碼就屬于符合要求的公共樣式。
為避免對所有細(xì)小更改都進(jìn)行整體布局,瀏覽器采用了一種“dirty 位”系統(tǒng)。如果某個呈現(xiàn)器發(fā)生了更改,或者將自身及其子代標(biāo)注為“dirty”,則需要進(jìn)行布局。
有兩種標(biāo)記:“dirty”和“children are dirty”?!癱hildren are dirty”表示盡管呈現(xiàn)器自身沒有變化,但它至少有一個子代需要布局。
在瀏覽器層面已經(jīng)考慮到了因為某些細(xì)小改動而發(fā)生全局重新計算和布局的情況。所以虛擬DOM的出現(xiàn)只是為了避免很多人為的行為導(dǎo)致的不必要重排,從而提升性能。
如果布局是由“大小調(diào)整”或呈現(xiàn)器的位置(而非大?。└淖兌|發(fā)的,那么可以從緩存中獲取呈現(xiàn)器的大小,而無需重新計算。
在某些情況下,只有一個子樹進(jìn)行了修改,因此無需從根節(jié)點開始布局。這適用于在本地進(jìn)行更改而不影響周圍元素的情況,例如在文本字段中插入文本(否則每次鍵盤輸入都將觸發(fā)從根節(jié)點開始的布局)。
Tali Garsiel and Paul Irish的這篇文章很長,也很有深度,適合反復(fù)閱讀,幾次是很難完全理解的,而且涉及的知識面非常之廣,要徹底弄明白,至少也成了半個瀏覽器專家和排版專家了。不過這是有意義的。本文是針對其中部分疑點做了擴(kuò)展閱讀,還有很多不明白的地方,之后抽時間深入涉獵。
作者:愛編程的光頭強(JM20110222)
版權(quán)聲明:轉(zhuǎn)載請注明出處,理解作者碼字的辛苦,謝謝!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/116233.html
摘要:瀏覽器顯示及交互背后的原理引子因為筆者愛編程的光頭強近期在寫一本關(guān)于小程序入門的書籍。不基于瀏覽器背后的運行原理,是很難說清楚虛擬被引入的真正原因和最大好處的。它是瀏覽器的核心部分。 瀏覽器顯示及交互背后的原理 引子 因為筆者(愛編程的光頭強)近期在寫一本關(guān)于小程序入門的書籍。其中有一章是介紹虛擬DOM的,它是位于Javascript和真正DOM之間的一層緩存層。為什么引入它,為什么它...
摘要:斯坦福宣布使用作為計算機(jī)課程的首選語言近日,某位有年教學(xué)經(jīng)驗的斯坦福教授決定放棄,而使用作為計算機(jī)入門課程的教學(xué)語言。斯坦福官方站點將它們新的課程描述為是最流行的構(gòu)建交互式的開發(fā)語言,本課程會用講解中的實例。 前端每周清單第 11 期:Angular 4.1支持TypeScript 2.3,Vue 2.3優(yōu)化服務(wù)端渲染,優(yōu)秀React界面框架合集 為InfoQ中文站特供稿件,首發(fā)地址為...
摘要:為了更加高效的網(wǎng)絡(luò)層,它需要不僅僅只是扮演套接字管理員的角色。用套接字池來組織套接字,以源來分組套接字,每個套接字池強制限制其連接數(shù)和安全約束。協(xié)商是一個為計算機(jī)網(wǎng)絡(luò)提供通信安全的加密協(xié)議。 原文請查閱這里,略有改動,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第十二章...
閱讀 3710·2021-11-19 09:40
閱讀 3164·2019-08-30 15:54
閱讀 2366·2019-08-30 15:44
閱讀 3253·2019-08-29 15:35
閱讀 3389·2019-08-29 12:22
閱讀 2914·2019-08-28 18:01
閱讀 3205·2019-08-26 13:54
閱讀 968·2019-08-26 12:24