爲何說DOM操做慢

DOM對象自己也是一個js對象,因此嚴格來講,並非操做這個對象慢,而是說操做了這個對象後,會觸發一些瀏覽器行爲,好比佈局(layout)和繪製(paint)css

瀏覽器是如何呈現一張頁面的

一個瀏覽器有許多模塊,其中負責呈現頁面的是渲染引擎模塊,比較熟悉的有WebKit和Gecko等,這裏也只會涉及這個模塊的內容。瀏覽器

  先用文字大體闡述下這個過程:佈局

  • 解析HTML,並生成一棵DOM tree
  • 解析各類樣式並結合DOM tree生成一棵Render tree
  • 對Render tree的各個節點計算佈局信息,好比box的位置與尺寸
  • 根據Render tree並利用瀏覽器的UI層進行繪製

  其中DOM tree和Render tree上的節點並不是一一對應,好比一個"display:none"的節點就只會存在於DOM tree上,而不會出如今Render tree上,由於這個節點不須要被繪製。性能

  paint是一個耗時的過程,然而layout是一個更耗時的過程,咱們沒法肯定layout必定是自上而下或是自下而上進行的,甚至一次layout會牽涉到整個文檔佈局的從新計算。字體

  可是layout是確定沒法避免的,因此咱們主要是要最小化layout的次數。code

什麼狀況下瀏覽器會進行layout

在考慮如何最小化layout次數以前,要先了解何時瀏覽器會進行layout。對象

  layout(reflow)通常被稱爲佈局,這個操做是用來計算文檔中元素的位置和大小,是渲染前重要的一步。在HTML第一次被加載的時候,會有一次layout以外,js腳本的執行和樣式的改變一樣會致使瀏覽器執行layout,這也是本文的主要要討論的內容。隊列

  通常狀況下,瀏覽器的layout是lazy的,也就是說:在js腳本執行時,是不會去更新DOM的,任何對DOM的修改都會被暫存在一個隊列中,在當前js的執行上下文完成執行後,會根據這個隊列中的修改,進行一次layout。文檔

  然而有時但願在js代碼中馬上獲取最新的DOM節點信息,瀏覽器就不得不提早執行layout,這是致使DOM性能問題的主因。it

  以下的操做會打破常規,並觸發瀏覽器執行layout:

  • 經過js獲取須要計算的DOM屬性
  • 添加或刪除DOM元素
  • resize瀏覽器窗口大小
  • 改變字體
  • css僞類的激活,好比:hover
  • 經過js修改DOM元素樣式且該樣式涉及到尺寸的改變
相關文章
相關標籤/搜索