浏览器渲染原理
什么是DOCTYPE及作用
DTD是一系列的語法規則,用來定義XML或(X)HTML的文件類型。瀏覽器會使用它來判斷文檔類型,決定使用何種協議來解析,以及切換瀏覽器模式。
DOCTYPE是用來聲明文檔類型和DTD規范的,一個主要的作用是文件的合法性驗證。如果文件代碼不合法,那么瀏覽器解析時便會出一些差錯。
瀏覽器的工作流程
- 解析HTML,生成DOM樹,解析CSS生產CSSOM
- 根據生成的DOM和CSSOM構建渲染樹Render tree
- 根據渲染樹,計算每個節點在屏幕上的位置,尺寸等信息。
- 將渲染樹繪制到屏幕上
注意:渲染對象和Dom元素相對應,但這種對應關系不是一對一的,不可見的Dom元素不會被插入渲染樹,例如head元素。另外,display屬性為none的元素也不會在渲染樹中出現(visibility屬性為hidden的元素將出現在渲染樹中)。
重排(reflow)和重繪(repaint)
當頁面元素的幾何屬性發生改變時會發生重排,當元素的屬性的該變沒有影響到幾何屬性時發生重繪。重排一定會發生重繪,但重繪不一定會引起重排。
什么時候發生重排
- 添加或刪除可見的DOM元素
- 元素位置發生該變
- 元素的尺寸發生該變(包括:外邊距,內邊距,邊框厚度,寬度,高度等屬性)
- 內容改變,例如文本內容該變,或圖片被另外一張不同尺寸的圖片代替
- 頁面渲染器初始化
由于每次重排都會產生計算消耗,大多數瀏覽器通過隊列化修改并批量執行來優化重排過程,獲取布局信息的操作會導致隊列刷新,如下面的這些屬性和方法需要返回最新的布局信息,所以瀏覽器會刷新渲染隊列并引發重排,應盡量避免使用。
- clientWidth、clientHeight、clientTop、clientLeft
- offsetWidth、offsetHeight、offsetTop、offsetLeft
- scrollWidth、scrollHeight、scrollTop、scrollLeft
- scrollIntoView()、scrollIntoViewIfNeeded()
- getComputedStyle()
- getBoundingClientRect()
- scrollTo()
什么時候發生重繪
當頁面中元素樣式的該變不影響布局時,發生重繪。比如:該變color,background,visibility等
思考下面兩段代碼:
代碼一:
代碼二:
var foo = document.getElementById('fooBar'); foo.style.color = 'blue'; var margin = parseInt(foo.style.marginTop); foo.style.marginTop = (margin + 10) + 'px';上面兩端代碼分別發生多少次重排和重繪?
代碼一:一次重排和重繪;代碼二:一次重排和一次重排和重繪
為什么會這樣呢?
當修改一個DOM節點時,修改的操作會先緩存到隊列,隊列中的修改會在下次UI線程執行時批量更新。修改過的節點會被標記為‘臟’(Dirty),獲取臟節點的屬性會導致隊列中的更新操作立刻執行。所以第二段代碼的不同之處在于var margin = parseInt(foo.style.marginTop);引發了一次重排。
如何減少重排和重繪的次數
- 避免對同一個DOM節點進行讀和寫操作的交叉進行。
- 使用display:none臨時從文檔中移除,添加完元素后在顯示它
- 使用document fragment
- 為需要修改的節點創建一個備份,然后對副本進行操作,修改完后用其代替舊節點(cloneNode)
- 使用position為absolute或fixed的元素創建動畫
- window.requestAnimation()
- 虛擬DOM庫
參考資料:
How browsers work
《高性能JavaScript》
總結
- 上一篇: outlook vba开发要点
- 下一篇: mybatis中mapUnderscor