探討css中repaint和reflow


(個人blog遷移文章。)

前言:

頁面設計中,不可避免的需要瀏覽器進行repaint和reflow。那到底什么是repaint和reflow呢。下面談談自己對repaint和reflow的理解,以及結合其他技術牛的講解,談談如何優化repaint和reflow。

初步介紹:

開發一個頁面時,不可避免的需要進行repaint和reflow。也就只有古來的靜態頁面才會不存在repaint和reflow。repaint主要是針對某一個DOM元素進行的重繪,reflow則是回流,針對整個頁面的重排。字面意思來說:repaint就是重繪,reflow就是回流。repaint和reflow的目的是:展示一個新的頁面樣貌。

嚴重性:

在性能優先的前提下,性能消耗 reflow大於repaint。

體現:

repaint是某個DOM元素進行重繪;reflow是整個頁面進行重排,也就是頁面所有DOM元素渲染。

如何觸發:

style變動造成repaint和reflow。

不涉及任何DOM元素的排版問題的變動為repaint,例如元素的color/text-align/text-decoration等等屬性的變動。

除上面所提到的DOM元素style的修改基本為reflow。例如元素的任何涉及長、寬、行高、邊框、display等style的修改。

常見觸發場景:

  1. 觸發repaint:
    1. color的修改,如color=#ddd;
    2. text-align的修改,如text-align=center;
    3. a:hover也會造成重繪。
    4. :hover引起的顏色等不導致頁面回流的style變動。
    5. 等等太多,一時間寫出來也太難想了。
  2. 觸發reflow:
    1. width/height/border/margin/padding的修改,如width=778px;
    2. 動畫,:hover等偽類引起的元素表現改動,display=none等造成頁面回流;
    3. appendChild等DOM元素操作;
    4. font類style的修改;
    5. background的修改,注意着字面上可能以為是重繪,但是瀏覽器確實回流了,經過瀏覽器廠家的優化,部分background的修改只觸發repaint,當然IE不用考慮;
    6. scroll頁面,這個不可避免;
    7. resize頁面,桌面版本的進行瀏覽器大小的縮放,移動端的話,還沒玩過能拖動程序,resize程序窗口大小的多窗口操作系統。
    8. 讀取元素的屬性(這個無法理解,但是技術達人是這么說的,那就把它當做定理吧):讀取元素的某些屬性(offsetLeft、offsetTop、offsetHeight、offsetWidth、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()、currentStyle(in IE));

如何避免:

說避免那是不可能的,不然就是以前古老的靜態頁面了,沒有交互,那在現在看來,就是一個失敗的作品。所以,在我們進行網頁設計的時候,就必須盡量減少頁面的repaint和reflow。repaint和reflow的目的是為了展示一個新的頁面,那么我們在進行頁面交互時,盡量通過各種方法減少repaint和reflow但又能展示一個新的頁面的目的。所以下面將結合其他技術達人的建議,通過自己的理解,給大家講解如何避免和優化repaint和reflow:

下面是大神Nicole Sullivan的原話:

  1. Change classes on the element you wish to style (as low in the dom tree as possible)
  2. Avoid setting multiple inline styles
  3. Apply animations to elements that are position fixed or absolute
  4. Trade smoothness for speed
  5. Avoid tables for layout
  6. Avoid JavaScript expressions in the CSS (IE only)
  1. 盡可能在DOM末梢通過改變class來修改元素的style屬性:盡可能的減少受影響的DOM元素。
  2. 避免設置多項內聯樣式:使用常用的class的方式進行設置樣式,以避免設置樣式時訪問DOM的低效率。
  3. 設置動畫元素position屬性為fixed或者absolute:由於當前元素從DOM流中獨立出來,因此受影響的只有當前元素,元素repaint。
  4. 犧牲平滑度滿足性能:動畫精度太強,會造成更多次的repaint/reflow,犧牲精度,能滿足性能的損耗,獲取性能和平滑度的平衡。
  5. 避免使用table進行布局:table的每個元素的大小以及內容的改動,都會導致整個table進行重新計算,造成大幅度的repaint或者reflow。改用div則可以進行針對性的repaint和避免不必要的reflow。
  6. 避免在CSS中使用運算式:學習CSS的時候就知道,這個應該避免,不應該加深到這一層再去了解,因為這個的后果確實非常嚴重,一旦存在動畫性的repaint/reflow,那么每一幀動畫都會進行計算,性能消耗不容小覷。

參考文獻:

  1. 頁面重構應注意的repaint和reflow
  2. 如何減少瀏覽器repaint和reflow(上)
  3. 回流與重繪:CSS性能讓JavaScript變慢?
  4. Reflows & Repaints: CSS Performance making your JavaScript slow?

 

覺得有用,點個贊,贊贊更健康。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM