記Chrome的效能分析工具實踐

網易考拉前端團隊發表於2018-01-29

業務場景

事情的起因是我們WMS系統內有一個批量列印的功能,今天倉庫反應第一次列印的速度大概是2s,但是之後每次都越來越慢,到後面頁面基本就直接卡死了。

從這個表現來看,這個問題基本可以定位成效能問題,而不是可以被try...catch到的異常。

想到的解決方案有兩種:

  1. 一行行review這部分相關的程式碼,console+debugger來逐步排查問題。
  2. 使用Chrome自帶的效能分析工具來定位問題。

一直沒找到什麼實踐機會來使用這部分功能來定位問題,這次有了真實的業務場景,果斷希望能用第二種方案來準確定位到問題。

記憶體洩露?

從表現上來看,感覺像是每次批量列印的時候導致了一部分記憶體洩漏,然後記憶體佔比越來越高導致瀏覽器卡死。

這時候就需要用Chrome的Memory功能來統計下記憶體佔比。在Memory下選擇Take heap snapshop,分析完成之後可以看到當前頁面的各種物件的記憶體佔比。當前我關注的不用那麼細,只需要關注到頁面的總記憶體,我在每次批量列印完成後都重新統計了頁面佔的記憶體,可以發現:每次記憶體佔用有輕微上升,但肯定不會導致頁面卡死。至此,可以排除掉是記憶體洩漏導致的問題。

記Chrome的效能分析工具實踐

使用Timeline分析

排除到記憶體洩漏的問題後,我能想到的頁面被卡住的原因是JS指令碼的執行時間過長。因為瀏覽器的渲染是單執行緒的,如果當前瀏覽器在進行JS指令碼計算,那麼在這個過程中UI執行緒是沒法同時進行渲染改變的,所以看起來就是頁面卡頓了。

這時候就需要用Chrome的Timeline分析工具(新版本Chrome裡改成Performance)來檢視每一個函式呼叫的時長,來定位出問題的具體函式。

點選record按鈕之後,然後多次呼叫批量列印功能,結束錄製。得到了如圖的分析結果:

記Chrome的效能分析工具實踐

從圖中可以明顯看出第一次列印到第三次列印耗時增加很多,其中黃色部分代表指令碼執行時間,紫色部分代表渲染時間。增加的時間部分主要是指令碼執行時間導致的,這時候需要定位具體是哪個函式導致的指令碼執行時間增加。

這時候可以檢視火焰圖部分,橫座標代表了消耗時間,縱座標是呼叫棧關係,上面的棧呼叫下面的棧。一直從上往下找到最內層的函式呼叫,發現了導致耗時增加的函式是JsBarcode,一個生成條形碼的函式。

記Chrome的效能分析工具實踐

為了驗證這個結論,在程式碼裡先註釋掉這個函式,重新執行Timeline分析。得到如圖的分析結果:

記Chrome的效能分析工具實踐

可以看到因為指令碼執行導致的時間增加問題已經解決了,但是渲染的時間還是隨著每一次的列印都會增加,這時候開始分析渲染的問題。檢視渲染部分詳情可以看到右上角的一個三角形,這個三角形代表這裡存在異常,並且Chrome給出了相應的警告(Forced reflow):

記Chrome的效能分析工具實踐

也就是說這裡強制重繪了介面,但是至此還是沒理解為什麼會重新繪製頁面,這裡強大的Chrome直接給出了影響渲染的程式碼片段,scrollbar-width這個檔案是element-ui的一個工具函式。

這時候檢視element-ui原始碼對這個檔案的引用情況,一層層往上定位發現在當前頁面使用到的table元件和message-box元件裡都引用到了這個檔案。table元件會在列表資料重新整理的時候呼叫到這個函式,而message-box會在彈出的時候呼叫到這個函式。

為了驗證這個猜想,註釋掉列表更新和彈框的程式碼,重新使用Timeline分析,發現剛才的三角形不見了,這時候頁面被重新繪製的問題也找到了。

記Chrome的效能分析工具實踐

至此,導致增加列印時長的兩個問題 1. 指令碼執行 2. 頁面渲染 都已經被定位到了,但是導致問題的業務程式碼還沒改呢!也就是為什麼繪製條形碼的函式和重繪頁面的時間會越來越長呢?

解決問題

問題已經分析到這了,很輕易想到了這部分功能裡唯一一句相關的DOM操作程式碼,在每次列印一張快遞單的時候都會appendChild一段DOM到body上(為了繪製二維碼以及轉canvas匯出圖片),但是每次appendChild之後並沒有去remove掉這段冗餘的DOM(逃。

回滾debugger的時候的修改程式碼,新增removeChild操作。重新執行Timeline分析,可以看到三次列印的耗時已經一致了。明天讓QA小哥哥測試一下可以上線了~

記Chrome的效能分析工具實踐

總結

最終定位到錯誤比較低階,不過這次實踐基本是從Chrome強大的效能分析工具定位到了問題,雖然如果採用方案1去review code來排查最終也能定位到問題。但是可以想象,當業務程式碼足夠複雜,函式呼叫層級很深的時候,去review code來排查的效率就會遠不如利用Timeline分析的效率高了。

今天聽了雲音樂的校園十佳,寫了一篇部落格,忽然想吟詩一首,苟利國家生死以(逃

author by yeomanyang

參考資料

更多精彩內容,請關注網易考拉前端團隊微信公眾號

image

相關文章