開篇
作為一個前端開發者,與我們打交道最多的就是瀏覽器,那麼問題就來了,如今市面上瀏覽器那麼多,但是那一個是最適合最好用的前端開發工具呢?也許不用說,大家都會異口同聲的說出是Chrome吧,為什麼呢,就我個人看來,它總是積極擁抱新的技術,而且還有很好用的開發除錯工具等等吧。所以今天我們就來說一說瀏覽器的問題,瀏覽器一般都由使用者介面,瀏覽器引擎,渲染引擎(排版引擎),JavaScript引擎,UI後端,網路模組和資料的持久化儲存這幾個模組組成。今天,我們主要說的就是瀏覽器的渲染引擎。由於JavaScript引擎越來越獨立,所以一般現在說的瀏覽器核心主要指的就是渲染引擎(Webkit,Gecko)
渲染引擎的作用
渲染引擎解析html文件,css文件,將解析後的css規則應用到html標籤元素上,最後將html渲染到瀏覽器視窗中以顯示具體的DOM內容
渲染引擎的工作流程
1.解析HTML構建DOM樹 -> 2.構建渲染樹 -> 3.渲染樹佈局階段 -> 4.繪製渲染樹
複製程式碼
- 解析HTML構建DOM樹:渲染引擎將HTML標籤解析成由多個DOM元素物件節點組成的具有父子關係的DOM樹結構
- 構建渲染樹:根據DOM樹結構的每個節點順序提前計算使用的css規則並重新計算DOM樹結構的樣式資料,生成一個帶樣式描述的DOM渲染樹物件
- 渲染樹佈局:根據渲染樹節點在頁面中的大小和位置,將渲染樹節點固定到頁面的位置上,在這個階段只要是元素的佈局屬性(position,float,margin等屬性)生效
- 繪製渲染樹:將渲染樹節點的背景、顏色、文字等樣式資訊應用到節點上,這個階段主要輸樣式的內部顯示樣式(color、background等屬性)生效
!:渲染引擎對DOM渲染樹的解析和輸出是逐行進行的。所以渲染樹前面的內容可以先渲染展示,這樣就保證了較好的使用者體驗。其次也不要在HTML中插入script指令碼等標籤,由於script標籤內容的解釋執行常常會阻塞頁面結構的渲染
在這裡我們需要注意的是在渲染樹佈局和繪製階段:
- 頁面重排(reflow):頁面在生成後如果頁面元素位置發生改變,一旦頁面reflow則必定會repaint
- 頁面重繪(repaint):顯示樣式發生改變但是佈局即元素位置不發生改變
reflow產生的代價要遠大於repaint,所以我們要儘量避免reflow,減少repaint
渲染引擎渲染DOM的主要流程
在這裡我們以webkit和gecko為例,這兩種渲染引擎工作流程的區別主要在於解析HTML或者css文件渲染的過程 webkit中HTML和CSS解析我們可以認為是並行的,而gecko則是先解析HTML,生成內容Sink後再開始解析CSS。當然它們在工作過程中所使用的描述術語也是不一樣的:
- webkit渲染物件被稱為 Render Tree (渲染樹)
- gecko 渲染物件唄成為 Frame Tree(Frame樹)
Webkit核心渲染DOM流程
Gecko核心渲染DOM流程
HTML解析和CSS解析階段
一般的渲染引擎都包好了HTML解析和CSS解析階段,這也就是渲染引擎解析流程中最重要的兩個階段。
- HTML文件解析
-
渲染引擎:逐行解析HTMl文字字串生成具有父子關係的DOM物件節點的過程
html在解析完成後會生成由多個DOM元素物件組成的DOM樹,解析時會對HTML文字標籤進行分析,每個標籤都會有DOM型別:
-
例如:
<html> (HTMLHtmlElement)
<head> (HTMLHeadElement)
<body> (HTMLBodyElement)
....
複製程式碼
在這裡需要注意的是DOM元素標籤和DOM元素物件雖然都是用來描述DOM結構的,但DOM元素標籤是指文字化的HTML標識,而DOM元素物件則是指經過渲染引擎DOM解析後生產的具有節點父子關係的樹形物件。
- CSS 文件解析
- css解析和html解析方式大體上是一樣的,首先也要通過詞法解析生成css分析樹,使用特定的css文班語法來實現,不同的是,html是使用類似xml結構的語法解析方式來完成分析的。
在渲染樹逐漸生成的的階段,DOM樹中的節點會在css分析樹中根據元素、類、id選擇器來提取與之對應元素的一條或者多條CSSRule,進行CSS規則的層疊和權重計算,得到最終生效的樣式CSSRule並新增到DOM樹上,形成渲染樹。每當DOM節點提取CSS樣式完成時,DOM渲染樹就形成了。
在已經形成的DOM渲染樹中,節點的CSS規則可以通過 document.defaultView.getComputedStyle(element,null) 方法檢視
如果一個節點有多條不同的樣式規則,則它是通過計算權重的方式來得到結果的
權重規則: !important > 內聯樣式規則(1000) > id(100) > 類選擇器(10) > 元素選擇器(1)
結語
瞭解這些瀏覽器渲染知識有助於我們解決與優化前端開發過程中的各種問題,本文旨在瞭解基本的渲染流程和一些基本的概念,當然,這只是我個人在學習過程中瞭解到的,也是一篇我自己學習當中的總結與記錄,也許還有我不瞭解的,如果有錯誤或者不清楚含糊的地方,希望大家可以指出來,我必定積極改正。謝謝大家!