瀏覽器如何渲染頁面?
這裡是修真院前端小課堂,每篇分享文從
【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴充套件思考】【更多討論】【參考文獻】
八個方面深度解析前端知識/技能,本篇分享的是:
【瀏覽器如何渲染頁面?】
一、背景介紹
瀏覽器是前端工程師或頁面重構師工作中必不可少的,WEB頁面執行在各種各樣的瀏覽器當中,瀏覽器載入、渲染頁面的速度直接影響著使用者體驗,特別是瀏覽器渲染頁面的原理,頁面渲染就是瀏覽器將HTML程式碼根據CSS定義的規則顯示在瀏覽器視窗中的這個過程,理解了原理就更會容易理解前端優化的一些準則。
二、知識剖析
2.1 reflow(迴流)
說到頁面為什麼會慢?那是因為瀏覽器要花時間、花精力去渲染,尤其是當它發現某個部分發生了點變化影響了佈局,需要倒回去重新渲染, 該過程稱為reflow(迴流)。
reflow幾乎是無法避免的。現在介面上流行的一些效果,比如樹狀目錄的摺疊、展開(實質上是元素的顯 示與隱藏)等,都將引起瀏覽器的reflow。滑鼠滑過、點選……只要這些行為引起了頁面上某些元素的佔位面積、定位方式、邊距等屬性的變化,都會引起它內部、周圍甚至整個頁面的重新渲 染。通常我們都無法預估瀏覽器到底會reflow哪一部分的程式碼,它們都彼此相互影響著。
2.2 repaint(重繪)
如果只是改變某個元素的背景色、文 字顏色、邊框顏色等等不影響它周圍或內部佈局的屬性,將只會引起瀏覽器repaint(重繪)。repaint的速度明顯快於reflow(在IE下需要換一下說法,reflow要比repaint更緩慢)。
下面是一個開啟Wikipedia時的Layout/reflow的視訊(注:HTML在初始化的時候也會做一次reflow,叫intial reflow),你可以感受一下:視訊
三、常見問題
瀏覽器如何渲染頁面?
四、解決方案
4.1瀏覽器工作大流程
先看圖
1)瀏覽器會解析三個東西:
一個是HTML/SVG/XHTML,事實上,Webkit有三個C++的類對應這三類文件。解析這三種檔案會產生一個DOM Tree。
CSS,解析CSS會產生CSS規則樹。
Javascript,指令碼,主要是通過DOM API(Application Programming Interface)和CSSOM(CSS物件模型) API來操作DOM Tree和CSS Rule Tree.
2)解析完成後,瀏覽器引擎會通過DOM Tree和CSS Rule Tree來構造Rendering Tree。注意:
Rendering Tree渲染樹並不等同於DOM樹,因為一些像Header或display:none的東西就沒必要放在渲染樹中了。CSS的Rule Tree主要是為了完成匹配並把CSS Rule附加上Rendering Tree上的每個Element。也就是DOM結點。也就是所謂的Frame。然後,計算每個Frame(也就是每個Element)的位置,這又叫layout和reflow過程。
3)最後通過呼叫作業系統Native GUI的API繪製。
4.2 DOM解析
上面這段HTML會解析成這樣:
下面是另一個有SVG標籤的情況:
4.3 CSS解析
CSS的解析大概是下面這個樣子(下面主要說的是Firefox的玩法),假設我們有下面的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元素是一個相當複雜和有效能問題的事情。所以,你就會在N多地方看到很多人都告訴你,DOM樹要小,CSS儘量用id和class,千萬不要過渡層疊下去,……
通過這兩個樹,我們可以得到一個叫Style Context Tree,也就是下面這樣(把CSS Rule結點Attach到DOM Tree上):
所以,Firefox基本上來說是通過CSS解析 生成CSS Rule Tree,然後,通過比對DOM生成Style Context Tree,然後Firefox通過把Style Context Tree和其Render Tree(Frame Tree)關聯上,就完成了。注意:Render Tree會把一些不可見的結點去除掉。而Firefox中所謂的Frame就是一個DOM結點,不要被其名字所迷惑了。
4.4渲染
渲染的流程基本上如下(黃色的四個步驟):
1)計算CSS樣式;2)構建Render Tree;3)Layout –定位座標和大小,是否換行,各種position, overflow, z-index屬性……;4)正式開畫;
注意:上圖流程中有很多連線線,這表示了Javascript動態修改了DOM屬性或是CSS屬會導致重新Layout,有些改變不會,就是那些指到天上的箭頭,比如,修改後的CSS rule沒有被匹配到,等。
5.編碼實戰
詳見視訊
六、擴充套件思考
1.影響頁面渲染速度主要因素有哪些?
reflow(迴流)和repaint(重繪)
2.哪些情況下會導致reflow發生?
改變窗囗大小;改變文字大小;新增/刪除樣式表;內容的改變,如使用者在輸入框中敲字;啟用偽類,如:hover (IE裡是一個兄弟結點的偽類被啟用);操作class屬性;指令碼操作DOM;計算offsetWidth和offsetHeight;設定style屬性。
3.如何避免reflow(迴流)?
reflow是不可避免的,只能將reflow對效能的影響減到最小。
1.儘可能限制reflow的影響範圍。需要改變元素的樣式,不要通過父級元素影響子元素。最好直接加在子元素上。
2.通過設定style屬性改變結點樣式的話,每設定一次都會導致一次reflow。所以最好通過設定class的方式。
3.減少不必要的DOM層級(DOM depth)。改變DOM樹中的一級會導致所有層級的改變,上至根部,下至被改變節點的子節點。這導致大量時間耗費在執行reflow上面。
4.避免不必要的複雜的CSS選擇器,尤其是後代選擇器(descendant selectors),因為為了匹配選擇器將耗費更多的CPU。
七、參考文獻
參考一:瀏覽器的渲染原理簡介
八、更多討論
1.提高瀏覽器效能的方法還有哪些?
2.瀏覽器的主要功能有哪些?
3.哪款瀏覽器的綜合性能最優?
“我們相信人人都可以成為一個工程師,現在開始,找個師兄,帶你入門,學習的路上不再迷茫。
這裡是技能樹.IT修真院:http://www.jnshu.com,初學者轉行到網際網路行業的聚集地。"
歡迎加IT交流群565734203與大家一起討論交流