瀏覽器渲染原理

什麼是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';
foo.style.marginTop = '30px';

代碼二:優化

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》線程

相關文章
相關標籤/搜索