繼續上篇《瀏覽器地址欄裏輸入URL後的全過程》javascript
爲何要了解瀏覽器的渲染原理?瞭解瀏覽器的渲染原理有什麼好處?咱們作前端開發爲何非要了解瀏覽器的原理?直接把網頁作出來,什麼需求,直接一把梭,擼完收工很差嗎。css
可是常常會有人會問,什麼是重排和重繪?html
重排也叫迴流(Reflow
),重繪(Repaint
),會影響到瀏覽器的性能,給用戶的感受就是網頁訪問慢,或者網頁會卡頓,不流暢,從而使網頁訪問量降低。前端
因此,想要儘量的避免重排和重繪,就須要瞭解瀏覽器的渲染原理。java
上圖咱們能夠看出,瀏覽器會解析三個模塊:web
HTML
,SVG
,XHTML
,解析生成DOM
樹。CSS
解析生成CSS
規則樹。JavaScript
用來操做DOM API
和CSSOM API
,生成DOM Tree
和CSSOM API
。解析完成後,瀏覽器會經過已經解析好的DOM Tree
和 CSS
規則樹來構造 Rendering
Tree
。shell
Rendering Tree
渲染樹並不等同於DOM
樹,由於一些像Header
或display:none
的東西就不必放在渲染樹中了。瀏覽器
CSS
的 Rule Tree
主要是爲了完成匹配並把CSS Rule
附加上Rendering
。性能優化
Tree
上的每一個Element
。也就是DOM
結點,即Frame
。而後,計算每一個Frame
(也就是每一個Element
)的位置,這又叫layout
和reflow
過程。app
最後經過調用操做系統Native GUI
的API
繪製。
webkit
內核的渲染流程,和整體渲染流程差很少,要構建
HTML
的
DOM Tree
,和
CSS
規則樹,而後合併生成
Render Tree
,最後渲染。
這個是
Mozilla
的
Gecko
渲染引擎。
Frame
樹時,二者叫法不一致,
webkit
稱之爲
Layout
,
Gecko
叫作
Reflow
。
HTML
,若是遇到了外鏈的css
,會一下載css
,一邊解析HTML
。css
下載完成後,會繼續解析css
,生成css Rules tree
,不會影響到HTML
的解析。<script>
標籤時,一旦發現有對javascript
的引用,就會當即下載腳本,同時阻斷文檔的解析,等腳本執行完成後,再開始文檔的解析。DOM
樹和CSS
規則樹已經生成完畢後,構造 Rendering Tree
。重排意味着元件的幾何尺寸變了,咱們須要從新驗證並計算Render Tree
。是Render Tree
的一部分或所有發生了變化。這就是Reflow
,或是Layout
。
重排由於要從新計算Render Tree
,並且每個DOM Tree
都有一個reflow
方法,一旦某個節點發生重排,就有可能致使子元素和父元素甚至是同級其餘元素的reflow
,浪費大量的時間從新驗證Render Tree
。
所以,重排的成本要比重繪高不少。
如下操做會致使重排或重繪。
DOM
元素節點。DOM
的位置,開啓動畫的時候。CSS
樣式,改變元素的大小,位置時,或者將使用display:none
時,會形成重排;修改CSS
顏色或者visibility:hidden
等等,會形成重繪。offsetWidth
和offsetHeight
。若是當前網頁含有一些動畫,或者固定不動元素的網頁時,因爲滾動也會發生重排,一旦發生滾動,當前瀏覽器所承受的壓力很大,就會形成網頁的卡頓,掉幀等狀況。
var bstyle = document.body.style; // cache
bstyle.padding = "20px"; // reflow, repaint
bstyle.border = "10px solid red"; // 再一次的 reflow 和 repaint
bstyle.color = "blue"; // repaint
bstyle.backgroundColor = "#fad"; // repaint
bstyle.fontSize = "2em"; // reflow, repaint
// new DOM element - reflow, repaint
document.body.appendChild(document.createTextNode('dude!'));
複製代碼
以上邏輯,幾乎每一步都會形成重排或重繪,若是瀏覽器像這樣處理的話,可能現代的瀏覽器沒有咱們使用的那麼流暢了。
所以瀏覽器有一個機制,會把須要重排或重繪的先積累着,而後一次性進行重排和重繪。
固然,不是全部的狀況瀏覽器都是這樣處理的,好比resize
或者修改默認字體,對於這些操做,瀏覽器會立馬進行重排。
因此咱們在監聽resize
事件時,通常咱們都會作防抖和節流。
style
的使用,對於須要操做DOM
元素節點,從新命名className
,更改className
名稱。clone
元素,能夠先把元素經過documentFragment
放入內存中,等操做完畢後,再appendChild
到DOM
元素中。dispaly:none
,可使用visibility:hidden
代替,dispaly:none
會形成重排,visibility:hidden
會形成重繪。Table
佈局,由於一個小小的操做,可能就會形成整個表格的重排或重繪。resize
事件時,作防抖和節流處理。absolute / fixed
屬性。參考文章: