性能:深刻理解瀏覽器渲染原理 reflow & repaint

剛入行前端的時候是否是常常看到有文章說盡可能不要用CSS通配符*,CSS選擇器層疊最好不要超過三層,HTML少使用table,結構也要儘可能簡單一些...這一切說的不無道理,過多的使用確實會形成瀏覽器渲染的性能下降,當你認識了reflow和repaint以後,你會發現這些還真不能用太多。前端

1、瀏覽器渲染過程

不一樣的瀏覽器渲染過程實際上並不相同(由渲染引擎決定),可是依舊存在一致的部分,大體過程以下圖:瀏覽器

圖片描述

  1. 解析HTML以構建DOM樹:渲染引擎解析HTML文檔,轉換樹中的HTML標籤或JS生成的標籤生成DOM節點
  2. 解析CSS以構建樣式結構體:渲染引擎解析CSS(包括外部CSS文件、樣式元素以及JS生成的樣式)成樣式結構體,根據CSS選擇器計算出節點的樣式
  3. 構建渲染樹:從根節點遞歸調用,計算每個元素的大小、位置以及每一個節點所應該出如今屏幕上的精確座標
  4. 繪製渲染樹:渲染引擎遍歷渲染樹將其繪製出來

2、什麼是 reflow & repaint

其實在上面瀏覽器渲染過程當中的第三步和第四步分別就是迴流(reflow)和重繪(repaint)。當第一次打開一個頁面時,至少會有一次迴流和重繪。以後,若是渲染樹發生了變更,那麼可能會觸發迴流或重繪中的一個或兩者。緩存

迴流:若是渲染樹的節點發生告終構性變化,例如寬高、位置、隱藏上有變化時,那麼就會觸發一次迴流
重繪:若是渲染樹的節點發生了非結構性變化,例如背景色、顏色、字體上有變化時,那麼就會觸發一次重繪佈局

迴流必將引發重繪,而重繪不必定會引發迴流。迴流的成本比重繪的成本要高得多,由於一個節點的迴流頗有可能致使子結點,父節點回流。性能

3、觸發 reflow & repaint

  • 頁面初始化渲染
  • DOM元素的添加、修改、刪除
  • 移動DOM或着DOM發生了動畫
  • resize瀏覽器窗口、滾動頁面
  • 修改DOM元素的字體顏色
  • 激活CSS僞類
  • 某個樣式的添加、修改、刪除
  • display: none會觸發reflow,visibility: hidden只會觸發repaint,由於沒有發生位置變化
  • 讀取元素的某些屬性(沒想到吧...)

現代瀏覽器會對迴流作優化,它會等到足夠數量的變化發生,再作一次批處理迴流。可是當獲取某些屬性時,瀏覽器爲了得到正確的值也會提早觸發迴流,這樣就使得瀏覽器的優化失效了,這些屬性包括offsetLeft、offsetTop、offsetWidth、offsetHeight、 scrollTop/Left/Width/Height、clientTop/Left/Width/Height、調用了getComputedStyle()或者IE的currentStyle字體

4、減小 reflow & repaint

迴流和重繪是不可避免的,咱們只能說將它們對性能的影響減到最小,既然咱們知道什麼狀況會觸發它們,那就從這些方面入手:優化

  1. 讓須要改變的元素進行「離線處理」,處理完後一塊兒更新動畫

    • 使用DocumentFragment進行緩存操做,觸發一次迴流和重繪
    • 使用display: none,觸發兩次迴流和重繪(因爲display: none的元素不在渲染樹中,對隱藏的元素操做不會引起其餘元素的迴流,能夠先隱藏它,操做完成後再顯示。這樣只在隱藏和顯示時觸發2次迴流)
  2. 將須要屢次迴流的元素的position屬性設爲absolute或fixed(設爲float沒有徹底脫離文檔流,這個很微妙),這樣元素就脫離了文檔流,它的變化不會影響到其餘元素的佈局,不會致使一個完整迴流
  3. 不要把DOM節點的屬性值放在一個循環裏做爲循環的變量,這會致使大量地讀寫這個節點的屬性
  4. 不要一條一條地修改樣式,將屢次改變樣式屬性的操做合併成一次(通常人也不會這樣作)
  5. 不要用table佈局,table中某個元素一旦觸發迴流就會致使table裏全部的其它元素迴流。在適合用table的場合,能夠設置table-layout爲auto或fixed,這樣可讓table一行一行的渲染,這種作法也是爲了限制迴流的影響範圍(通常咱們能夠經過ul li的佈局替代之)
  6. 避免使用CSS的JavaScript表達式(這種規則已過期)

總之,在之後的開發中咱們要儘可能避免大量、頻繁的操做DOM元素,由於DOM操做的代價實在是太昂貴了(這也是Virtual DOM應運而生的緣由)。在書寫HTML時要避免沒必要要的層級,書寫CSS時避免嵌套過深、規則過於複雜,尤爲是後代選擇器,匹配選擇器也會耗費更多的CPU。spa

相關文章
相關標籤/搜索