性能優(yōu)化例子:使用Performance工具分析性能瓶頸,解決頁面卡頓!
對于前端的性能優(yōu)化,優(yōu)化手段其實(shí)是非常多的,但是不能盲目的進(jìn)行優(yōu)化,一定要先分析出項(xiàng)目的性能瓶頸,否則只會做無用功。那么如何才能更好的分析出項(xiàng)目的瓶頸呢?其實(shí)最關(guān)鍵的就是要分析頁面的整個(gè)加載過程,找出有問題的地方再進(jìn)行優(yōu)化。使用谷歌瀏覽器自帶的 Performance 工具可以幫我們解決這個(gè)問題,下面通過一個(gè)例子來進(jìn)行分析優(yōu)化!
在優(yōu)化之前,我們先要了解一些知識,比如瀏覽器的渲染幀、Performance 工具的使用,這樣才有助于更好地理解優(yōu)化的過程!
瀏覽器的渲染幀
對于渲染,我們首先需要了解一個(gè)概念:設(shè)備刷新率。設(shè)備刷新率是設(shè)備屏幕渲染的頻率,通俗一點(diǎn)就是,把屏幕當(dāng)作墻,設(shè)備刷新率就是多久重新粉刷一次墻面?;疚覀兤匠=佑|的設(shè)備,如手機(jī)、電腦,它們的默認(rèn)刷新頻率都是 60FPS,也就是屏幕在 1s 內(nèi)渲染 60次,約 16.7ms 渲染一次屏幕。這就意味著,我們的瀏覽器最佳的渲染性能就是所有的操作在一幀 16.7ms 內(nèi)完成,能否做到一幀內(nèi)完成直接決定著渲染性,影響用戶交互。
瀏覽器的 fps 指瀏覽器每一秒的幀數(shù),fps 越大,每秒的畫面就越多,瀏覽器的顯示就越流暢。
圖片
標(biāo)準(zhǔn)渲染幀:在一個(gè)標(biāo)準(zhǔn)幀渲染時(shí)間 16.7ms之內(nèi),瀏覽器需要完成 Main 線程的操作,并 commit 給 Compositor 進(jìn)程
圖片
丟幀:主線程里操作太多,耗時(shí)長,commit 的時(shí)間被推遲,瀏覽器來不及將頁面 draw 到屏幕,這就丟失了一幀
圖片
在瀏覽器的一個(gè)渲染幀(16.7ms)里,會存在一段時(shí)間,叫做空閑時(shí)間(idle period),如果完成各種任務(wù)的執(zhí)行以及頁面渲染的工作等的時(shí)間少于 16.7 ms,那么這一幀就會存在空閑時(shí)間,可以把一些耗時(shí)操作拆分開來,然后在每一幀的空閑時(shí)間中去執(zhí)行。
圖片
所謂的頁面卡頓、首屏加載慢,根本原因都是執(zhí)行長任務(wù),使得頁面的渲染時(shí)機(jī)推后,在每一幀里得不到渲染,從而造成用戶的不好體驗(yàn)。要想解決用戶體驗(yàn)差的問題,那么就需要知道瀏覽器渲染過程中的每一幀都干了些啥任務(wù),是啥原因?qū)е落秩緯r(shí)機(jī)推后,這個(gè)時(shí)候我們就需要借助瀏覽器性能檢測工具 Performance 來進(jìn)行分析,然后再做針對性的優(yōu)化,下面我們來了解下該工具的具體使用。
Performance工具的使用
圖片
簡單的使用教程:
在 Chrome 瀏覽器中,按下 F12 鍵或右鍵點(diǎn)擊頁面并選擇 "檢查",打開開發(fā)者工具面板。
在開發(fā)者工具中,切換到 "Performance"(性能)選項(xiàng)卡,你會看到一個(gè)記錄性能數(shù)據(jù)的界面。
圖片
點(diǎn)擊頁面頂部的 "Record"(錄制)按鈕,開始記錄性能數(shù)據(jù),刷新頁面或執(zhí)行你想要分析的操作。
圖片
在你完成操作后,點(diǎn)擊 "Stop"(停止)按鈕,停止記錄性能數(shù)據(jù)。此時(shí),會看到一個(gè)包含了各種性能數(shù)據(jù)的時(shí)間軸圖表。
圖片
時(shí)間軸圖表將顯示頁面加載期間的各種事件,如 JavaScript 執(zhí)行、網(wǎng)絡(luò)請求、繪制等??梢钥s放和選擇特定時(shí)間段來深入分析。
圖片
性能優(yōu)化分析的例子
谷歌官方提供的一個(gè) Demo:googlechrome.github.io/devtools-sa…[2]
左側(cè)有一些按鈕,點(diǎn)擊 Stop 小球停止運(yùn)動,點(diǎn)擊 Add、Subtract 可以控制小球數(shù)量的增減,比較有意思的一個(gè)點(diǎn)是,當(dāng)小球的數(shù)量越來越多,頁面會越來越卡頓,如果點(diǎn)擊 Optimize(優(yōu)化),那么頁面就會恢復(fù)正常。
優(yōu)化前的效果展示
當(dāng)小球數(shù)量很多時(shí),頁面會非??D:
圖片
使用工具分析性能
接下來借助 Performance 來分析頁面卡頓的原因:
圖片
錄制大概 4 秒鐘,可以看到該頁面的性能確實(shí)存在很大的問題,我們首先分析這張圖里面的一些內(nèi)容:
總覽區(qū): 可以看到每個(gè)階段的具體耗時(shí),這里很明顯是渲染占據(jù)了 90% 的時(shí)間,而 JS 腳本的執(zhí)行、頁面繪制并不耗時(shí),現(xiàn)在已經(jīng)可以定位到是渲染存在問題。
圖片
幀: 綠色代表該幀正常,黃色表示丟幀
圖片
主線程:
圖片
以其中的一個(gè) Task 為例:標(biāo)紅代表該任務(wù)是長任務(wù)(一般認(rèn)為超過 50ms 的任務(wù)是長任務(wù)),往下是該任務(wù)具體的細(xì)節(jié),比如這個(gè) Task 里主要執(zhí)行了 Animation Frame Fired 方法,它里面調(diào)用了 Function Call,F(xiàn)unction Call 里面調(diào)用了 app.update 的方法,一層一層往下調(diào)用執(zhí)行,然后在 app.update 下面我們可以看到很多紫色的線條,紫色代表回流重繪。
圖片
現(xiàn)在可以初步下結(jié)論:頻繁的回流重繪導(dǎo)致頁面卡頓,后面還要再進(jìn)行分析才能確定。
接下來點(diǎn)擊其中的一個(gè)任務(wù),觀察 Call Tree,每個(gè)方法的執(zhí)行時(shí)間都能看到,以及時(shí)間的占比
圖片
我們的分析目標(biāo)主要是尋找花費(fèi)時(shí)間長的任務(wù),依次點(diǎn)開,可以發(fā)現(xiàn) 90% 的時(shí)間是花費(fèi)在 Layout,點(diǎn)擊右側(cè)進(jìn)入源碼:
圖片
圖片
分析這段代碼我們已經(jīng)可以知道問題出在哪里了,讀取offsetTop會觸發(fā)回流重繪,這里用了個(gè) for 循環(huán),所以當(dāng)小球的數(shù)量越來越多的時(shí)候,不斷的讀取 offsetTop 屬性,導(dǎo)致頻繁的觸發(fā)回流重繪,最終頁面卡頓。
頻繁的回流重繪導(dǎo)致卡頓
我們需要解答兩個(gè)問題:
- 為什么頻繁的回流重繪會導(dǎo)致卡頓?
計(jì)算復(fù)雜度: 回流涉及到重新計(jì)算元素的位置和幾何屬性,這可能需要遍歷整個(gè)DOM樹,并重新計(jì)算樣式。這個(gè)計(jì)算過程比較復(fù)雜,尤其是在大型、復(fù)雜的頁面上。
渲染的停頓: 當(dāng)發(fā)生回流時(shí),瀏覽器可能需要停止渲染,重新計(jì)算布局,然后再重新繪制,這可能導(dǎo)致頁面的停頓或閃爍。
頻繁觸發(fā): 如果在用戶與頁面交互的過程中頻繁地觸發(fā)回流和重繪,可能會導(dǎo)致性能問題。比如,在滾動頁面時(shí),如果頻繁改變元素的樣式,可能會引起多次回流和重繪,從而影響流暢度。
也就是說,頻繁的回流重繪可以看做是耗時(shí)嚴(yán)重的任務(wù),阻礙了頁面的渲染,從而導(dǎo)致卡頓!
- 為什么讀取 offsetTop 屬性會觸發(fā)回流重繪?
這與瀏覽器的優(yōu)化機(jī)制有關(guān):由于每次回流與重繪都會帶來額外的計(jì)算消耗,為了優(yōu)化這個(gè)過程,大多數(shù)瀏覽器采用了隊(duì)列化修改并批量執(zhí)行的策略。瀏覽器會將修改操作添加到隊(duì)列中,直至一定時(shí)間段過去或操作達(dá)到閾值時(shí),才會清空隊(duì)列。
然而,當(dāng)需要獲取布局信息時(shí),瀏覽器會強(qiáng)制刷新隊(duì)列。這意味著,當(dāng)你讀取元素的布局信息如 offsetTop、offsetLeft 等時(shí),需要返回最新的布局信息,因此瀏覽器不得不清空隊(duì)列,觸發(fā)回流和重繪操作以返回正確的值。
如何進(jìn)行優(yōu)化
那么如何進(jìn)行優(yōu)化呢?知道是 offsetTop 的問題后,不用這個(gè)屬性就行了,我們看下這個(gè)例子的處理方式:
圖片
使用 style.top 屬性取代 offsetTop 即可,當(dāng)然這兩個(gè)屬性也有一定的區(qū)別,這里不再展開,這樣就能完美的解決頁面卡頓的問題!
總的來說,其實(shí)優(yōu)化方法很簡單,最關(guān)鍵的是要找出頁面的性能瓶頸,到底是哪里影響了性能。因此,前端開發(fā)者想要提升自己的能力、提升自己對性能優(yōu)化的理解,就必須具備熟悉瀏覽器的渲染原理、使用 Performance 工具、分析項(xiàng)目的性能瓶頸等方面的能力!