首頁 > 軟體

JS網頁repaint與reflow 的區別及優化方式

2022-09-12 18:01:40

引言

相信作為程式設計師的我們,都知道前端三劍客,HTML、CSS、JS,不僅前端工程師,可能後端工程師勉強也能硬寫幾行 CSS,CSS 可以說是最容易入門、最難以精通的“坑”,曾經採訪過好幾個後端工程師,幾乎都一致表示後端轉向全棧最最讓他們打退堂鼓的,都是 CSS,為什麼這麼說呢?其實 CSS 最大的問題是,很多基礎教學對於 CSS 的呈現,基本都是零零散散,單一的呈現效果,而真正到了實際應用,堆疊了很多元素,很多樣式的時候, CSS 的很多“奇怪”的特效就會在不知不覺中發揮出來,讓非專業的 “CSS 工程師” 現場抓狂。

即使 CSS 非常難以駕馭,但是作為前端工程師的我們,這可是我們賴以吃飯的技能呀,因此,在對於瀏覽器渲染相關原理的理解後,其實還是能夠總結出一些行之有效的規範的,遵循這些規範來走,也就能夠最大程度地避開不必要的坑,也能夠進一步對相關網頁進行優化,提高網頁的效能和體驗,接下來就讓我們一起來了解一下與 CSS 渲染過程息息相關的兩個問題 repaint 與 reflow ,看看我們能從中總結出什麼 CSS 避坑技巧。

repaint 與 reflow 是什麼?

repaint 重繪,重新繪製,顧名思義,在原來的位置重新畫上新的東西,主要表示的是顏色變化等觸發的 CSS 重新渲染的過程

reflow 重排,也叫回流,重新排列,表達的是在原來的基礎上,對元素的相對位置進行重新編排,計算相對應的位置時觸發的渲染過程

repaint 和 reflow 什麼時候觸發?

就目前普遍的網頁來看,除了遠古時期的靜態頁面之外的所有現代化頁面,基本上都存在非常多的互動邏輯,只要互動邏輯觸發了相對應的網頁變化,也就會觸發 repaint 或者 reflow,也就是說動態網頁,隨時都會觸發 repaint 或者 reflow,比如進行彈窗、新增或者刪除某個網頁元素,或者播放網頁動畫等等都是觸發 repaint 或者 reflow 的操作

repaint 與 reflow 的區別

repaint 與 reflow 的區別主要是觸發方式的不同,元素的外觀、比如顏色、背景色、邊框顏色等變化,而位置和大小並沒有變化,則會觸發 repaint ,重新渲染元素的外觀,而如果是位置和大小等,以及觸發其他元素位置變化的動作,則會觸發 reflow。

由於 reflow 會觸發元素位置相關的計算,因此相比 repaint,reflow 的消耗更小,因此,我們需要儘量避免不必要的 reflow。

如何優化 repaint 和 reflow

我們都知道傳送 repaint 或者 reflow 都會對網頁效能造成一定的影響,因此,在滿足正常功能的前提下,我們應該想辦法儘量減少發生 repaint 和 reflow,這樣理論對網頁效能會有一定的優化作用

使用防抖和節流優化

在許多網頁會存在許多觸發式的互動,比如點選按鈕、輸入框自動搜尋等,也就是我們進行操作,網頁會同步進行相應反饋的功能,那麼這種功能在使用過程中,由於操作的頻繁發生,會同步觸發頻繁的 repaint 與 reflow,因此我們可以通過防抖以及節流兩種方式來對相關的反饋動作進行優化。

防抖

防抖,這裡可以舉一個形象的比喻,很多相機都有防抖功能,那麼我們可以想象,每次我們都是左右抖,抖完了之後,再進行拍照,也就是 忽略前面的多次觸發,只執行最後一次

例如我們有一個輸入框,然後輸入框有一個自動搜尋關鍵詞的功能,原來是每次關鍵詞變化,立刻進行搜尋,那麼會觸發非常多次的請求,同時也會觸發非常多次的頁面回顯,這個時候,我們就應該採取防抖來進行優化,優化後的效果是,當我們輸入停止 500ms 後再進行搜尋,並且如果在 500ms 內關鍵詞出現變化,則重新計算時間,直到關鍵詞保持 500ms 沒有變化才進行搜尋,範例程式碼如下

var timer = null
function toggle(){
  timer && clearTimeout(timer)
  timer = setTimeout(() => {
   // 執行目的函數
  }, delay);
}

節流

節流我們可以理解為規定單位時間內只能有多少流量,即單位時間內所做的動作的量是一定的,也就是說 當我們執行了某個動作後,一定要等待一定的時間後觸發才有效果,例如,當我們網頁裡有某個按鈕作為事件開關時,我們可以對它進行節流優化,這樣,在使用者非正當操作時,也就是頻繁觸發按鈕時,網頁也能夠按規定的時間執行正常的邏輯,不會因為頻繁觸發出現bug,範例程式碼如下

// 標記是否上鎖
var isLock = false
function toggle(){
  // 如果在鎖定時間內,直接不執行,退出函數
  if(isLock) return
  // 執行目的函數
  // 加鎖,delay 後開啟
  isLock = true
  setTimeout(() => {
    isLock = false 
  }, delay);
}

規範書寫 CSS 的順序

這個說法一直備受爭議,很多博主一直在討論和實驗驗證這個問題,這裡作為晚輩我也不過多討論,秉承著理論的原則,我覺得一方面理論上這種做法是可以達到效能優化的,那麼我們也就可以這樣做做,另一方面,對於規範 CSS 的寫法問題,即使沒有優化作用,也依然值得我們學習,規範自己書寫 CSS 的方式,不僅便於我們自己偵錯程式碼,也能夠使得我們在共同作業開發中相互閱讀程式碼,理解對方的思路,這裡就簡單列舉書寫順序供大家參考,有其他意見的可以多多補充

1、佈局相關的屬性

例如:display、position、float、left、top、right、bottom、overflow、clear、z-index 等

2、自身屬性

例如:width、height、padding、border、margin、background 等

3、文字屬性

例如:font-family、font-size、font-style、font-weight、font-varient、color

4、文字屬性

例如:text-align、vertical-align、text-wrap、text-transform、text-indent、text-decoration、letter-spacing、word-spacing、white-space、text-overflow 等

5、CSS 等新特性

例如:content、box-shadow、border-radius、transform 等

總結

對於 CSS 這種非常非常基礎的技能,其實才是我們最應該花時間規範和優化的東西,因為它太基礎了,所以很多時候都被大家所忽略,正式因為它是最基礎的,最簡單的,我們更應該好好學習如何優化以及如何更加規範地書寫他,這樣,隨著我們專案的不斷擴大、專案參與成員不斷增多,才不至於讓專案成為岌岌可危的 “高樓”,穩紮穩打,才能走得更遠

以上就是JS網頁repaint與reflow 的區別及優化方式的詳細內容,更多關於JS網頁repaint reflow優化的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com