两句css 搞定页面滚动时的卡顿问题?
前言
對(duì)于網(wǎng)頁的卡頓性能優(yōu)化,我們首先想到的肯定是從JavaScript開始。但這個(gè)鍋js表示不背😂,但不是js的原因又會(huì)是什么原因了?文章內(nèi)容不多,只要你能仔細(xì)看完,相信一定能對(duì)你有所幫助。
在實(shí)際項(xiàng)目中React、Vue、Angular三大框架都有使用過,其在開發(fā)效率上是毋庸置疑的,但在某些場(chǎng)景上其性能確是差強(qiáng)人意的。如果大家有遇到此類場(chǎng)景,歡迎在下方留言討論。
下面我們一起來了解一下實(shí)際項(xiàng)目中遇到的此類性能瓶頸是如何處理的!
背景
項(xiàng)目基于VUE,由于業(yè)務(wù)要求需要長列表渲染(不能做動(dòng)態(tài)加載和虛擬列表), 列表數(shù)據(jù)過多時(shí)滾動(dòng)條的scrollTop達(dá)到5w+ , 同時(shí)頁面中每一列的一些元素通過websocket實(shí)時(shí)更新。 在首屏加載、頁面滾動(dòng)、篩選等交互時(shí),頁面發(fā)生比較嚴(yán)重的卡頓問題首先還是著手優(yōu)化js的相關(guān)部分
1. 篩選部分使用服務(wù)端渲染 2. 低頻使用的隱藏元素全部v-if 3. 列表每列的元素標(biāo)簽盡可能減少 4. 部分交互方法優(yōu)化,部分使用了jquery 原生化 5. Vue computed 中高頻觸發(fā)的方法寫到vuex中按需觸發(fā)(服務(wù)端渲染時(shí)也需要使用) 6. 每列的懸浮組件前置(提升到列表父級(jí)組件) 7. 事件委托(減少每列的事件綁定) ...優(yōu)化過后整體性能有所提升,但是當(dāng)列表數(shù)量較多時(shí),滾動(dòng)列表還是能感受到明顯的卡頓。
兩句css 搞定頁面滾動(dòng)時(shí)的卡頓問題
其實(shí)頁面卡頓就是一種用戶體驗(yàn),怎樣評(píng)判這種體驗(yàn)的好壞了,根據(jù)FPS(frame per second),即一秒之間能夠完成多少次重新渲染,顯示器的刷新頻率一般是60Hz(在
電腦的顯示設(shè)置中可查),瀏覽器會(huì)自動(dòng)按照這個(gè)頻率刷新動(dòng)畫。每幀渲染的時(shí)間不能超過16.66ms(1000ms/60), 在實(shí)際開發(fā)中30fps-60fps 頁面都會(huì)比較流暢。
下面通過 chrome devtool 排查卡頓問題,在Performance 面板記錄了操作10s 的耗時(shí):
在瀏覽器中通過 frames可以非常清晰的看到每幀的用時(shí),用時(shí)最長的一幀將近1s(遠(yuǎn)大于16.67ms)。
如上圖,update layer tree和Paint 占用了71.2%的時(shí)間, 這個(gè)是啥?為什么會(huì)這么耗時(shí)了?從字面上看意思是更新層樹和繪制,實(shí)際上就是我們前端程序猿耳熟能詳?shù)闹嘏藕椭乩L。
非常需要注意的一點(diǎn)是:一個(gè)元素的重排通常會(huì)帶來一系列的反應(yīng),甚至觸發(fā)整個(gè)文檔所有元素的重排和重繪,性能代價(jià)是非常高昂的。
如何查看元素是否有連鎖的重繪?如何避免了?
我們可以通過如下設(shè)置后再操作頁面,重繪的區(qū)域在頁面中會(huì)有綠色邊框高亮顯示。
經(jīng)過排查后發(fā)現(xiàn)主要有兩種情況會(huì)引起頁面的連鎖重繪和重排,導(dǎo)致該頁面滾動(dòng)時(shí)卡頓:
case1: box-shadow的陰影區(qū)域和固定定位有交叉關(guān)系時(shí)。
如左側(cè)導(dǎo)航是固定定位,右側(cè)是列表部分,列表的外層元素添加了box-shadow,
其陰影區(qū)域和固定定位有交叉時(shí)。滾動(dòng)時(shí)固定定位會(huì)觸發(fā)重繪,通過box-shadow,
間接的使右側(cè)列表上所有元素都發(fā)生了重繪。
修復(fù):去掉該box-shadow屬性后滾動(dòng)列表非常順暢。
case2: websocket實(shí)時(shí)更新列表中某行中某個(gè)元素的數(shù)據(jù)時(shí),整個(gè)列表發(fā)生重繪。
解決這個(gè)問題,要先了解web頁面的層次問題。
有兩個(gè)因素造成了這個(gè)問題,其一是因?yàn)閿?shù)據(jù)變化時(shí)使用了animation導(dǎo)致了同一層次的元素重繪
修復(fù)方案一:刪除該animation屬性(因業(yè)務(wù)要求不可以取)
修復(fù)方案二:在該元素上增加相對(duì)定位,設(shè)置一個(gè)唯一的z-index值。使元素有獨(dú)立的層次,在瀏覽器渲染該元素時(shí)不會(huì)觸發(fā)連鎖重繪。
在問題排查中可以通過如下設(shè)置降低CPU的速度測(cè)試問題:
總結(jié)
在性能優(yōu)化上我們往往忽視了css的重要性,使得在優(yōu)化的路上越走越遠(yuǎn),最后不了了之。如果你也有這樣的經(jīng)歷,歡迎留言討論。
總之在開發(fā)過程中嚴(yán)謹(jǐn)?shù)陌芽睾米约旱拿恳恍写a,在面對(duì)復(fù)雜的問題時(shí),多分析和查閱資料,當(dāng)遇到性能瓶頸問題時(shí),可以多用chrome devtool上的相關(guān)設(shè)置進(jìn)行快速定位。
如果發(fā)現(xiàn)文章中有誤的地方歡迎指出。如果覺得有幫助,不妨點(diǎn)贊、關(guān)注支持一下,真心希望能和大家一起成長,一起進(jìn)步,非常感謝!
作者:tager
鏈接:https://juejin.cn/post/7020416550154797064
說明:稀土掘金同步更新
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
總結(jié)
以上是生活随笔為你收集整理的两句css 搞定页面滚动时的卡顿问题?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Carboxyrhodamine 110
- 下一篇: 木兰花--欧阳修