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