JS網(wǎng)頁repaint與reflow?的區(qū)別及優(yōu)化方式
引言
相信作為程序員的我們,都知道前端三劍客,HTML、CSS、JS,不僅前端工程師,可能后端工程師勉強(qiáng)也能硬寫幾行 CSS,CSS 可以說是最容易入門、最難以精通的“坑”,曾經(jīng)采訪過好幾個(gè)后端工程師,幾乎都一致表示后端轉(zhuǎn)向全棧最最讓他們打退堂鼓的,都是 CSS,為什么這么說呢?其實(shí) CSS 最大的問題是,很多基礎(chǔ)教程對于 CSS 的呈現(xiàn),基本都是零零散散,單一的呈現(xiàn)效果,而真正到了實(shí)際應(yīng)用,堆疊了很多元素,很多樣式的時(shí)候, CSS 的很多“奇怪”的特效就會(huì)在不知不覺中發(fā)揮出來,讓非專業(yè)的 “CSS 工程師” 現(xiàn)場抓狂。
即使 CSS 非常難以駕馭,但是作為前端工程師的我們,這可是我們賴以吃飯的技能呀,因此,在對于瀏覽器渲染相關(guān)原理的理解后,其實(shí)還是能夠總結(jié)出一些行之有效的規(guī)范的,遵循這些規(guī)范來走,也就能夠最大程度地避開不必要的坑,也能夠進(jìn)一步對相關(guān)網(wǎng)頁進(jìn)行優(yōu)化,提高網(wǎng)頁的性能和體驗(yàn),接下來就讓我們一起來了解一下與 CSS 渲染過程息息相關(guān)的兩個(gè)問題 repaint 與 reflow ,看看我們能從中總結(jié)出什么 CSS 避坑技巧。
repaint 與 reflow 是什么?
repaint 重繪,重新繪制,顧名思義,在原來的位置重新畫上新的東西,主要表示的是顏色變化等觸發(fā)的 CSS 重新渲染的過程
reflow 重排,也叫回流,重新排列,表達(dá)的是在原來的基礎(chǔ)上,對元素的相對位置進(jìn)行重新編排,計(jì)算相對應(yīng)的位置時(shí)觸發(fā)的渲染過程
repaint 和 reflow 什么時(shí)候觸發(fā)?
就目前普遍的網(wǎng)頁來看,除了遠(yuǎn)古時(shí)期的靜態(tài)頁面之外的所有現(xiàn)代化頁面,基本上都存在非常多的交互邏輯,只要交互邏輯觸發(fā)了相對應(yīng)的網(wǎng)頁變化,也就會(huì)觸發(fā) repaint 或者 reflow,也就是說動(dòng)態(tài)網(wǎng)頁,隨時(shí)都會(huì)觸發(fā) repaint 或者 reflow,比如進(jìn)行彈窗、添加或者刪除某個(gè)網(wǎng)頁元素,或者播放網(wǎng)頁動(dòng)畫等等都是觸發(fā) repaint 或者 reflow 的操作
repaint 與 reflow 的區(qū)別
repaint 與 reflow 的區(qū)別主要是觸發(fā)方式的不同,元素的外觀、比如顏色、背景色、邊框顏色等變化,而位置和大小并沒有變化,則會(huì)觸發(fā) repaint ,重新渲染元素的外觀,而如果是位置和大小等,以及觸發(fā)其他元素位置變化的動(dòng)作,則會(huì)觸發(fā) reflow。
由于 reflow 會(huì)觸發(fā)元素位置相關(guān)的計(jì)算,因此相比 repaint,reflow 的消耗更小,因此,我們需要盡量避免不必要的 reflow。
如何優(yōu)化 repaint 和 reflow
我們都知道發(fā)送 repaint 或者 reflow 都會(huì)對網(wǎng)頁性能造成一定的影響,因此,在滿足正常功能的前提下,我們應(yīng)該想辦法盡量減少發(fā)生 repaint 和 reflow,這樣理論對網(wǎng)頁性能會(huì)有一定的優(yōu)化作用
使用防抖和節(jié)流優(yōu)化
在許多網(wǎng)頁會(huì)存在許多觸發(fā)式的交互,比如點(diǎn)擊按鈕、輸入框自動(dòng)搜索等,也就是我們進(jìn)行操作,網(wǎng)頁會(huì)同步進(jìn)行相應(yīng)反饋的功能,那么這種功能在使用過程中,由于操作的頻繁發(fā)生,會(huì)同步觸發(fā)頻繁的 repaint 與 reflow,因此我們可以通過防抖以及節(jié)流兩種方式來對相關(guān)的反饋動(dòng)作進(jìn)行優(yōu)化。
防抖
防抖,這里可以舉一個(gè)形象的比喻,很多相機(jī)都有防抖功能,那么我們可以想象,每次我們都是左右抖,抖完了之后,再進(jìn)行拍照,也就是 忽略前面的多次觸發(fā),只執(zhí)行最后一次
例如我們有一個(gè)輸入框,然后輸入框有一個(gè)自動(dòng)搜索關(guān)鍵詞的功能,原來是每次關(guān)鍵詞變化,立刻進(jìn)行搜索,那么會(huì)觸發(fā)非常多次的請求,同時(shí)也會(huì)觸發(fā)非常多次的頁面回顯,這個(gè)時(shí)候,我們就應(yīng)該采取防抖來進(jìn)行優(yōu)化,優(yōu)化后的效果是,當(dāng)我們輸入停止 500ms 后再進(jìn)行搜索,并且如果在 500ms 內(nèi)關(guān)鍵詞出現(xiàn)變化,則重新計(jì)算時(shí)間,直到關(guān)鍵詞保持 500ms 沒有變化才進(jìn)行搜索,實(shí)例代碼如下
var timer = null function toggle(){ timer && clearTimeout(timer) timer = setTimeout(() => { // 執(zhí)行目的函數(shù) }, delay); }
節(jié)流
節(jié)流我們可以理解為規(guī)定單位時(shí)間內(nèi)只能有多少流量,即單位時(shí)間內(nèi)所做的動(dòng)作的量是一定的,也就是說 當(dāng)我們執(zhí)行了某個(gè)動(dòng)作后,一定要等待一定的時(shí)間后觸發(fā)才有效果,例如,當(dāng)我們網(wǎng)頁里有某個(gè)按鈕作為事件開關(guān)時(shí),我們可以對它進(jìn)行節(jié)流優(yōu)化,這樣,在用戶非正當(dāng)操作時(shí),也就是頻繁觸發(fā)按鈕時(shí),網(wǎng)頁也能夠按規(guī)定的時(shí)間執(zhí)行正常的邏輯,不會(huì)因?yàn)轭l繁觸發(fā)出現(xiàn)bug,示例代碼如下
// 標(biāo)記是否上鎖 var isLock = false function toggle(){ // 如果在鎖定時(shí)間內(nèi),直接不執(zhí)行,退出函數(shù) if(isLock) return // 執(zhí)行目的函數(shù) // 加鎖,delay 后打開 isLock = true setTimeout(() => { isLock = false }, delay); }
規(guī)范書寫 CSS 的順序
這個(gè)說法一直備受爭議,很多博主一直在討論和實(shí)驗(yàn)驗(yàn)證這個(gè)問題,這里作為晚輩我也不過多討論,秉承著理論的原則,我覺得一方面理論上這種做法是可以達(dá)到性能優(yōu)化的,那么我們也就可以這樣做做,另一方面,對于規(guī)范 CSS 的寫法問題,即使沒有優(yōu)化作用,也依然值得我們學(xué)習(xí),規(guī)范自己書寫 CSS 的方式,不僅便于我們自己調(diào)試代碼,也能夠使得我們在協(xié)作開發(fā)中相互閱讀代碼,理解對方的思路,這里就簡單列舉書寫順序供大家參考,有其他意見的可以多多補(bǔ)充
1、布局相關(guān)的屬性
例如: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 等
總結(jié)
對于 CSS 這種非常非?;A(chǔ)的技能,其實(shí)才是我們最應(yīng)該花時(shí)間規(guī)范和優(yōu)化的東西,因?yàn)樗A(chǔ)了,所以很多時(shí)候都被大家所忽略,正式因?yàn)樗亲罨A(chǔ)的,最簡單的,我們更應(yīng)該好好學(xué)習(xí)如何優(yōu)化以及如何更加規(guī)范地書寫他,這樣,隨著我們項(xiàng)目的不斷擴(kuò)大、項(xiàng)目參與成員不斷增多,才不至于讓項(xiàng)目成為岌岌可危的 “高樓”,穩(wěn)扎穩(wěn)打,才能走得更遠(yuǎn)
以上就是JS網(wǎng)頁repaint與reflow 的區(qū)別及優(yōu)化方式的詳細(xì)內(nèi)容,更多關(guān)于JS網(wǎng)頁repaint reflow優(yōu)化的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS圖形編輯器場景坐標(biāo)視口坐標(biāo)的相互轉(zhuǎn)換
這篇文章主要為大家介紹了JS圖形編輯器之場景坐標(biāo)視口坐標(biāo)的相互轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01uniapp五分鐘實(shí)現(xiàn)刷抖音小程序教程示例
這篇文章主要為大家介紹了uniapp五分鐘實(shí)現(xiàn)刷抖音小程序教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03JavaScript 運(yùn)行機(jī)制詳解再淺談Event Loop
這篇文章主要介紹了JavaScript 運(yùn)行機(jī)制詳解及淺談了Event Loop,感興趣的小伙伴可以和小編一起閱讀下面文章的具體內(nèi)容2021-09-09微信瀏覽器禁止頁面下拉查看網(wǎng)址實(shí)例詳解
這篇文章主要介紹了微信瀏覽器禁止頁面下拉查看網(wǎng)址實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06微信小程序中input標(biāo)簽詳解及簡單實(shí)例
這篇文章主要介紹了微信小程序中input標(biāo)簽詳解及簡單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05