瀏覽器顯示及交互背後的原理

瀏覽器顯示及交互背後的原理

引子

由於筆者(愛編程的光頭強)近期在寫一本關於小程序入門的書籍。其中有一章是介紹虛擬DOM的,它是位於Javascript和真正DOM之間的一層緩存層。爲何引入它,爲何它這麼流行,前端三大框架,小程序等,隨處可見它的身影。其背後原理是什麼。不基於瀏覽器背後的運行原理,是很難說清楚虛擬DOM被引入的真正緣由和最大好處的。css

爲了弄清楚瀏覽器背後運行的邏輯,我查了大量資料,不得不吐槽一下,互聯網知識儘管多,魚龍混雜、良莠不齊、錯漏百出,基本是常態,能找到一篇含金量十分高的文章是不容易的。很幸運,關於這個問題,我還真找到了一篇,本文就是對它的解讀。好記性不如爛筆頭。html

注:本文全部網址都是通過百度短網址處理過的,便於排版及美觀。前端

原文引用

正文

本文至關於一篇讀書筆記,咱們按照原文順序來一點點深刻。 瀏覽器市場份額佔比: Chrome 63.34% Safari 15.06% Firefox 4.48% Samsung Internet 3.77% UC Browser 3.58% Opera 2.58% 從以上瀏覽器份額,能夠看出,chrome佔絕對比,因此咱們的測試就基於它。css3

1、瀏覽器引擎

引擎的通俗解釋就是驅動器、發動機,在軟件中是以一套組件或者擴展程序、包存在的核心代碼,至關於計算機的CPU。Wikipedia的解釋是瀏覽器引擎即佈局引擎,排版引擎,渲染引擎等。Chrome、Safari使用的是Webkit引擎,Mozilla使用的是Gecho引擎,有時候也叫內核。參考:Dwz.Cn/Tr3rrt8mweb

以上定義對大衆是足夠的,但對於想搞清楚瀏覽器運行機制的人來講,不夠。很顯然,它籠統的將瀏覽器幾塊核心程序(引擎)統稱爲一個了,並使用其中一個做爲所有核心的代稱,這很容易讓人混淆。chrome

果真,stackoverflow就有人提到了這樣的混淆(dwz.cn/7ccPJcX6), 本文引用的以色列那位女工程師文章中,將瀏覽器組件分爲了7個,用戶界面(UI),瀏覽器引擎,呈現引擎,網絡,用戶界面後端,JavaScript 解釋器,數據存儲等。編程

ui,瀏覽器引擎,渲染引擎等之間關係圖

ui,瀏覽器引擎,渲染引擎等之間關係圖
ui,瀏覽器引擎,渲染引擎等之間關係圖

各瀏覽器使用的渲染/layout引擎及js引擎表

各瀏覽器使用的渲染/layout引擎及js引擎表
各瀏覽器使用的渲染/layout引擎及js引擎表

這裏的瀏覽器引擎到底指什麼呢,很顯然它並非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等(en.wikipedia.org/wiki/Browse…

在這種狀況下,估計不多有人知道有渲染引擎這個東西存在。

背景2:若是你正在和知道瀏覽器如何工做的朋友以及他們背後的全部瘋狂魔法交談......

此上下文中的瀏覽器引擎是指瀏覽器進程,主要負責管理全部I/o進程和顯示UI及跟渲染引擎通訊等。

瀏覽器引擎:在UI和渲染引擎之間編組操做。

這也是正確的。若是你看一下Chromium的架構,你會發現瀏覽器進程/引擎使用渲染進程來協調頁面內容。

此上下文中的渲染引擎是指構造DOM,執行JavaScript和佈局網頁的程序,例如Webkit,Gecko,Trident。渲染引擎由兩個主要組件組成:WebCore包含核心佈局功能,JavaScriptCore包含JavaScript解釋器V8。

您的朋友彷佛是專家,還必須瞭解渲染過程,該過程負責構建網頁。渲染引擎只是渲染過程當中的關鍵部分。

下圖顯示了Chromium體系結構的高級體系結構概述(Google Chrome開源版本)。若是您想了解更多有關現代瀏覽器背後的魔力的信息,能夠查看如下文章:medium.com/@zicodeng/e…

瀏覽器進程/線程通訊示意圖
瀏覽器進程/線程通訊示意圖

2、渲染引擎(呈現引擎)

對文檔或其餘資源進行解析後,渲染到瀏覽器窗口顯示。它是瀏覽器的核心部分。一般包含dom解析,css解析,生成render樹,layout/reflow,repaint,直至呈現給用戶。

3、內容8000個chunck(塊)

文中提到「內容的大小通常限制在 8000 個chunck塊之內」,解釋:Web服務器生成HTTP Response時沒法在Header就肯定消息大小的,這時通常來講服務器將不會提供Content-Length的頭信息,而採用Chunked編碼動態的提供body內容的長度。進行Chunked編碼傳輸的HTTP Response會在消息頭部設置: Transfer-Encoding: chunked

4、渲染過程

瀏覽器請求到HTML代碼後,在生成DOM的開始階段,並行發起css、圖片、js的請求。CSS文件下載完成後開始構建CSSOM。CSSOM構建完成後和DOM合併生成Render Tree(attachment)。瀏覽器計算出每一個節點在屏幕的位置進行佈局。佈局完成後,經過顯卡,將內容畫到屏幕上。JS修改了DOM或者CSS屬性後,Layout和Paint也會被重複執行。圖片下載完成後也須要調用Layout和Paint來更新網頁。

5、dom+cssom -> render tree

從dom,cssom到渲染樹(frame樹)的過程不一樣的內核樹的概念不太同樣的,不過所作的工做都大同小異,就是計算造成若干能用於佈局的矩形盒子(寬度、高度和位置等幾何信息,該計算過程具體實如今layout或reflow階段),box模型。

Gecko 將視覺格式化元素組成的樹稱爲「框架樹」。每一個元素都是一個框架。WebKit 使用的術語是「呈現樹」,它由「呈現對象」組成。對於元素的放置,WebKit 使用的術語是「佈局」,而 Gecko 稱之爲「重排」。對於鏈接 DOM 節點和可視化信息從而建立呈現樹的過程,WebKit 使用的術語是「附加」。有一個細微的非語義差異,就是 Gecko 在 HTML 與 DOM 樹之間還有一個稱爲「內容槽」的層,用於生成 DOM 元素。

6、樹及DOM節點

樹包含 DOM 節點,指的樹是由實現了某些DOM 接口的元素構成的。每一個元素都有一條原型鏈,標準定義了每一個DOM節點或元素必需要實現的DOM接口(屬性,方法,事件)。

7、添加defer,async的腳本預解析

一般html被解析的時候遇到js會阻塞執行,爲了優化體驗和速度,採用延遲或異步的方式,此時就存在了資源的預解析或異步執行的過程了。

8、共享樣式

共享樣式數據 WebKit 節點會引用樣式對象 (RenderStyle)。這些對象在某些狀況下能夠由不一樣節點共享。這些節點是同級關係,而且:

這些元素必須處於相同的鼠標狀態(例如,不容許其中一個是「:hover」狀態,而另外一個不是) 任何元素都沒有 ID 標記名稱應匹配 類屬性應匹配 映射屬性的集合必須是徹底相同的 連接狀態必須匹配 焦點狀態必須匹配 任何元素都不該受屬性選擇器的影響,這裏所說的「影響」是指在選擇器中的任何位置有任何使用了屬性選擇器的選擇器匹配 元素中不能有任何 inline 樣式屬性 不能使用任何同級選擇器。WebCore 在遇到任何同級選擇器時,只會引起一個全局開關,並停用整個文檔的樣式共享(若是存在)。這包括 + 選擇器以及 :first-child 和 :last-child 等選擇器。

代碼:

<div>
	<ul>
		<li>11</li>
		<li>22</li>
		<li>33</li>
	</ul>
</div>
複製代碼
div ul li{
	color: red;
	width: 100px;
	height: 36px;
}
複製代碼

以上代碼就屬於符合要求的公共樣式。

Dirty 位系統

爲避免對全部細小更改都進行總體佈局,瀏覽器採用了一種「dirty 位」系統。若是某個呈現器發生了更改,或者將自身及其子代標註爲「dirty」,則須要進行佈局。

有兩種標記:「dirty」和「children are dirty」。「children are dirty」表示儘管呈現器自身沒有變化,但它至少有一個子代須要佈局。

在瀏覽器層面已經考慮到了由於某些細小改動而發生全局從新計算和佈局的狀況。因此虛擬DOM的出現只是爲了不不少人爲的行爲致使的沒必要要重排,從而提高性能。

優化及虛擬DOM優化的基礎

若是佈局是由「大小調整」或呈現器的位置(而非大小)改變而觸發的,那麼能夠從緩存中獲取呈現器的大小,而無需從新計算。 在某些狀況下,只有一個子樹進行了修改,所以無需從根節點開始佈局。這適用於在本地進行更改而不影響周圍元素的狀況,例如在文本字段中插入文本(不然每次鍵盤輸入都將觸發從根節點開始的佈局)。

Tali Garsiel and Paul Irish的這篇文章很長,也頗有深度,適合反覆閱讀,幾回是很難徹底理解的,並且涉及的知識面很是之廣,要完全弄明白,至少也成了半個瀏覽器專家和排版專家了。不過這是有意義的。本文是針對其中部分疑點作了擴展閱讀,還有不少不明白的地方,以後抽時間深刻涉獵。

相關文章
相關標籤/搜索