瀏覽器如何渲染頁面?

大家好,我是IT修真院深圳分院第01期學(xué)員,一枚正直純潔善良的web程序員。

今天給大家分享一下,修真院官網(wǎng)CSS任務(wù)15,深度思考中的知識點——瀏覽器如何渲染頁面?

一、背景介紹

瀏覽器是前端工程師或頁面重構(gòu)師工作中必不可少的,WEB頁面運行在各種各樣的瀏覽器當(dāng)中,瀏覽器載入、渲染頁面的速度直接影響著用戶體驗,特別是瀏覽器渲染頁面的原理,頁面渲染就是瀏覽器將HTML代碼根據(jù)CSS定義的規(guī)則顯示在瀏覽器窗口中的這個過程,理解了原理就更會容易理解前端優(yōu)化的一些準(zhǔn)則。

二、知識剖析

2.1 reflow(回流)

說到頁面為什么會慢?那是因為瀏覽器要花時間、花精力去渲染,尤其是當(dāng)它發(fā)現(xiàn)某個部分發(fā)生了點變化影響了布局,需要倒回去重新渲染, 該過程稱為reflow(回流)。

reflow幾乎是無法避免的。現(xiàn)在界面上流行的一些效果,比如樹狀目錄的折疊、展開(實質(zhì)上是元素的顯 示與隱藏)等,都將引起瀏覽器的reflow。鼠標(biāo)滑過、點擊……只要這些行為引起了頁面上某些元素的占位面積、定位方式、邊距等屬性的變化,都會引起它內(nèi)部、周圍甚至整個頁面的重新渲 染。通常我們都無法預(yù)估瀏覽器到底會reflow哪一部分的代碼,它們都彼此相互影響著。

2.2 repaint(重繪)

如果只是改變某個元素的背景色、文 字顏色、邊框顏色等等不影響它周圍或內(nèi)部布局的屬性,將只會引起瀏覽器repaint(重繪)。repaint的速度明顯快于reflow(在IE下需要換一下說法,reflow要比repaint更緩慢)。

下面是一個打開Wikipedia時的Layout/reflow的視頻(注:HTML在初始化的時候也會做一次reflow,叫intial reflow),你可以感受一下:視頻

三、常見問題

瀏覽器如何渲染頁面?

四、解決方案

4.1瀏覽器工作大流程

先看圖

1)瀏覽器會解析三個東西:

一個是HTML/SVG/XHTML,事實上,Webkit有三個C++的類對應(yīng)這三類文檔。解析這三種文件會產(chǎn)生一個DOM Tree。

CSS,解析CSS會產(chǎn)生CSS規(guī)則樹。

Javascript,腳本,主要是通過DOM API(Application Programming Interface)和CSSOM(CSS對象模型) API來操作DOM Tree和CSS Rule Tree.

2)解析完成后,瀏覽器引擎會通過DOM Tree和CSS Rule Tree來構(gòu)造Rendering Tree。注意:

Rendering Tree渲染樹并不等同于DOM樹,因為一些像Header或display:none的東西就沒必要放在渲染樹中了。CSS的Rule Tree主要是為了完成匹配并把CSS Rule附加上Rendering Tree上的每個Element。也就是DOM結(jié)點。也就是所謂的Frame。然后,計算每個Frame(也就是每個Element)的位置,這又叫l(wèi)ayout和reflow過程。

3)最后通過調(diào)用操作系統(tǒng)Native GUI的API繪制。

4.2 DOM解析

上面這段HTML會解析成這樣:

下面是另一個有SVG標(biāo)簽的情況:

4.3 CSS解析

CSS的解析大概是下面這個樣子(下面主要說的是Firefox的玩法),假設(shè)我們有下面的HTML文檔:

于是DOM Tree是這個樣子

然后我們的CSS文檔是這樣的:

/* rule 1 */ doc { display: block; text-indent: 1em; }

/* rule 2 */ title { display: block; font-size: 3em; }

/* rule 3 */ para { display: block; }

/* rule 4 */ [class="emph"] { font-style: italic; }

于是我們的CSS Rule Tree會是這個樣子:

注意:CSS匹配HTML元素是一個相當(dāng)復(fù)雜和有性能問題的事情。所以,你就會在N多地方看到很多人都告訴你,DOM樹要小,CSS盡量用id和class,千萬不要過渡層疊下去,……

通過這兩個樹,我們可以得到一個叫Style Context Tree,也就是下面這樣(把CSS Rule結(jié)點Attach到DOM Tree上):

所以,F(xiàn)irefox基本上來說是通過CSS解析 生成CSS Rule Tree,然后,通過比對DOM生成Style Context Tree,然后Firefox通過把Style Context Tree和其Render Tree(Frame Tree)關(guān)聯(lián)上,就完成了。注意:Render Tree會把一些不可見的結(jié)點去除掉。而Firefox中所謂的Frame就是一個DOM結(jié)點,不要被其名字所迷惑了。

4.4渲染

渲染的流程基本上如下(黃色的四個步驟):

1)計算CSS樣式;2)構(gòu)建Render Tree;3)Layout –定位坐標(biāo)和大小,是否換行,各種position, overflow, z-index屬性……;4)正式開畫;

注意:上圖流程中有很多連接線,這表示了Javascript動態(tài)修改了DOM屬性或是CSS屬會導(dǎo)致重新Layout,有些改變不會,就是那些指到天上的箭頭,比如,修改后的CSS rule沒有被匹配到,等。

5.編碼實戰(zhàn)

詳見視頻


瀏覽器如何渲染頁面_騰訊視頻

六、擴展思考

1.影響頁面渲染速度主要因素有哪些?

reflow(回流)和repaint(重繪)

2.哪些情況下會導(dǎo)致reflow發(fā)生?

改變窗囗大?。桓淖兾淖执笮?;添加/刪除樣式表;內(nèi)容的改變,如用戶在輸入框中敲字;激活偽類,如:hover (IE里是一個兄弟結(jié)點的偽類被激活);操作class屬性;腳本操作DOM;計算offsetWidth和offsetHeight;設(shè)置style屬性。

3.如何避免reflow(回流)?

reflow是不可避免的,只能將reflow對性能的影響減到最小。

1.盡可能限制reflow的影響范圍。需要改變元素的樣式,不要通過父級元素影響子元素。最好直接加在子元素上。

2.通過設(shè)置style屬性改變結(jié)點樣式的話,每設(shè)置一次都會導(dǎo)致一次reflow。所以最好通過設(shè)置class的方式。

3.減少不必要的DOM層級(DOM depth)。改變DOM樹中的一級會導(dǎo)致所有層級的改變,上至根部,下至被改變節(jié)點的子節(jié)點。這導(dǎo)致大量時間耗費在執(zhí)行reflow上面。

4.避免不必要的復(fù)雜的CSS選擇器,尤其是后代選擇器(descendant selectors),因為為了匹配選擇器將耗費更多的CPU。

七、參考文獻

參考一:瀏覽器的渲染原理簡介

參考二:為什么每個前端開發(fā)者都要理解網(wǎng)頁渲染?

八、更多討論

1.提高瀏覽器性能的方法還有哪些?

2.瀏覽器的主要功能有哪些?

3.哪款瀏覽器的綜合性能最優(yōu)?

感謝大家觀看

今天的分享就到這里啦,歡迎大家點贊、轉(zhuǎn)發(fā)、留言、拍磚~

PPT鏈接

視頻鏈接

你可以直接點擊此鏈接與我一起學(xué)習(xí):邀請碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容