網(wǎng)頁渲染必須在很早的階段進行,可以早到頁面布局剛剛定型。因為樣式和腳本都會對網(wǎng)頁渲染產(chǎn)生關鍵性的影響。所以專業(yè)開發(fā)者必須了解一些技巧端辱,從而避免在實踐的過程中遇到性能問題。
Webkit渲染主要流程如下:
Mozilla的Gecko渲染引擎主要流程如下:
由圖可以發(fā)現(xiàn)虽画,兩個引擎過程基本相同舞蔽。主要有三個步驟:
1.解析。瀏覽器會解析HTML/SVG/XHTML码撰,事實上渗柿,webkit有三個C++的類對應這三類文檔。瀏覽器解析這三種文件會產(chǎn)生一個DOM Tree灸拍;解析CSS做祝,產(chǎn)生style rules;解析Javacript鸡岗,主要通過DOM API和CSSOM API來操作DOM Tree和CSS Rule Tree
2.解析完成后混槐,瀏覽器引擎會通過DOM Tree和CSS Rule Tree來構造Rendering Tree。
3.調(diào)用操作系統(tǒng)Native GUI的API繪制轩性。
兩者的語義差別:
webkit把可視化好的可視元素成為Render Tree,用Layout來表示元素的布局
Gecko把可視化好的可視元素成為Frame Tree声登,每個元素就是一個frame,元素的布局成為Reflow
還有一個細小的差別差別在于:Gecko在HTML與DOM樹之間還多一個層content Sink,這是創(chuàng)建DOM對象的工廠悯嗓。
1.解析 HTML 標簽, 構建 DOM 樹
一個是HTML/SVG/XHTML件舵,事實上,Webkit有三個C++的類對應這三類文檔脯厨。解析這三種文件會產(chǎn)生一個DOM Tree铅祸。創(chuàng)建一棵由一組待生成渲染的對象組成的渲染樹(在Webkit中這些對象被稱為渲染器或渲染對象,而在Gecko中稱之為“frame”合武。)渲染樹反映了文檔對象模型的結(jié)構临梗,但是不包含諸如<head>標簽或含有display:none屬性的不可見元素。在渲染樹中稼跳,每一段文本字符串都表現(xiàn)為獨立的渲染器盟庞。每一個渲染對象都包含與之對應的DOM對象,或者文本塊汤善,還加上計算過的樣式什猖。換言之,渲染樹是一個文檔對象模型的直觀展示红淡。
2.解析 CSS 標簽, 構建 CSSOM 樹
解析CSS會產(chǎn)生CSS規(guī)則樹不狮。
3.解析JavaScript,腳本
主要是通過DOM API和CSSOM API來操作DOM Tree和CSS Rule Tree.
4.把 DOM 和 CSSOM 組合成 渲染樹 (render tree)
Rendering Tree 渲染樹并不等同于DOM樹锉屈,因為一些像Header或display:none的東西就沒必要放在渲染樹中了荤傲。
CSS 的 Rule Tree主要是為了完成匹配并把CSS Rule附加上Rendering Tree上的每個Element。也就是DOM結(jié)點颈渊。也就是所謂的Frame。
5.在渲染樹的基礎上進行布局, 計算每個節(jié)點的幾何結(jié)構
6.把每個節(jié)點繪制到屏幕上 (painting)
Repaint重繪
當改變那些不會影響元素在網(wǎng)頁中的位置的元素樣式時终佛,譬如background-color(背景色)俊嗽, border-color(邊框色), visibility(可見性)铃彰,瀏覽器只會用新的樣式將元素重繪一次(這就是重繪绍豁,或者說重新構造樣式)。
Reflow重排
當改變影響到文本內(nèi)容或結(jié)構牙捉,或者元素位置時竹揍,重排或者說重新布局就會發(fā)生。reflow 會從<html>這個root frame開始遞歸往下邪铲,依次計算所有的結(jié)點幾何尺寸和位置芬位,在reflow過程中,可能會增加一些frame带到,比如一個文本字符串必需被包裝起來昧碉。這些改變通常由以下事件觸發(fā):
- DOM操作(元素添加,刪除,修改被饿,或者元素順序的改變);
- 容變化四康,包括表單域內(nèi)的文本改變;
- CSS屬性的計算或改變;
- 添加或刪除樣式表;
- 更改“類”的屬性;
- 瀏覽器窗口的操作(縮放,滾動);
- 偽類激活(:懸停)狭握。
注:display:none會觸發(fā)reflow闪金,而visibility:hidden只會觸發(fā)repaint,因為沒有發(fā)現(xiàn)位置變化论颅。
瀏覽器如何優(yōu)化渲染
瀏覽器盡可能將重繪/重構 限制在被改變元素的區(qū)域內(nèi)哎垦。比如,對于位置固定或絕對的元素嗅辣,其大小改變只影響元素本身及其子元素撼泛,然而,靜態(tài)定位元素的大小改變會觸發(fā)后續(xù)所有元素的重流澡谭。
另一種優(yōu)化技巧是愿题,在運行幾段JavaScript代碼時,瀏覽器會緩存這些改變蛙奖,在代碼運行完畢后再將這些改變經(jīng)一次通過加以應用潘酗。