上週接到一個效能問題的線上反饋:「浙江客戶xxx報表展示超過20秒,小明看了相關介面響應都在2秒內,希望我協助排查。」
聽完這個簡短的描述我猜測可能是客戶機房網路問題,為什麼這麼說呢,從描述中我提取到這麼幾個關鍵資訊「個例,不是所有客戶」、「後臺響應很快」,給我的感覺好像是機房出口頻寬滿了,當然這只是猜測,需要拿出具體的證據。
「信任但需要確認」,雖然我從研發口中得知後臺響應很快,但是為了查問題我還是把相關賬號要過來自己點了點,也看了後臺的access log的確不慢,通過瀏覽器的Network -> Timing奇怪的發現,有個提示會停留20s左右「CAUTION:request is not finished yet!(注意:請求尚未完成)」,之後才會展示各項指標耗時,但是耗時都不高。
這個表象似乎和我猜測機房出口頻寬滿的想法不謀而合,接下來就是剝繭抽絲,證實客戶機房網路的確有問題,提供證據讓實施反饋客戶,客戶再去問候資訊管理部,資訊管理部再去問候運營商(和toG的客戶打交道千萬要謹慎,往往都會驚動一個鏈條上的人)。
由於我不是專業網工,對於網路問題也只能憑藉自己的二把刀經驗來做一些診斷,如果有不對的地方,請大家一定要指正。
ping -n 50 xxx.com
我首先通過ping的方式來觀察是否有丟包情況,結論是網路良好,沒有任何丟包情況。
接下來我又通過Wireshark抓包分析,本機發出請求到收到響應的時間確實在2s之內,這樣看來報表展示慢和網路似乎是沒關係,還需要繼續挖掘原因。
強烈推薦大家學習Wireshark,對於網路學習、問題排查真的是一把利劍。
之前提出的疑點偏後端領域,現在排查一圈下來矛頭指向了前端,那就接著挖。
我看了報表頁面內的js程式碼,邏輯很簡單,就是ajax查詢資料然後呼叫前端框架的setData方法,到底是哪段js程式碼把整個頁面渲染給拖慢了呢。
我甚至懷疑是不是觸發了jquery框架的某個bug,為了證實這一點我將請求資料那段從jquery切到了最原始的XMLHttpRequest,依然很慢。
要是瀏覽器能記錄這個頁面渲染過程中發生了什麼,每個階段的耗時分佈,那排查問題就方便多了,我想到了曾經用過的skywalking、jaegertracing這類鏈路追蹤工具,排查後端效能問題很是方便。
最終藉助搜尋引擎找到了chrome的Performance,請搜尋「chrome 前端效能優化工具」詳細瞭解,真是好用,前後不到兩分鐘就找到了效能瓶頸點。
F12-Performance->點選開始記錄->重新整理頁面->等待頁面渲染完成->點選停止記錄
點選上圖紅框部分的Call Tree檢視呼叫鏈路和每個節點的耗時,重點關注耗時佔比較大的呼叫棧,如下圖所示拖慢整個頁面渲染的元凶是jCommon.js中的兩個設定表格樣式的函數。
這兩個函數的觸發時機在jCommon.js的$(function(){}中,屬於通用邏輯,之所以其他客戶沒有受到影響,是因為其他客戶對於表格的個性化設定沒有開啟,所以沒有執行,我大體看了一下邏輯內部有太多的遞迴+迴圈呼叫,遇到複雜(行列合併、巢狀)而且資料量大的表格就是一種噩夢,更細節的就不多說了,不是本篇的重點。
「讓專業的人幹專業的事」,因為前端我並不擅長,所以我將這個問題的根治任務拋給了前端同學,這塊程式碼是必須要優化的,太損耗效能。同時對於當下的問題我也給出了建議,在當前報表頁面暫時剔除這段邏輯,初衷是用來提升使用者體驗,現在看來已經嚴重影響到可用性。
透過一個簡單的效能問題,聊聊筆者排查的思路和中途用到一些工具,最終藉助瀏覽器的效能分析工具發現前端問題程式碼,對於陌生的領域一款良好的工具可以降低排查的門檻,事半功倍。
https://developer.chrome.com/docs/devtools/evaluate-performance/reference/
https://docs.microsoft.com/zh-cn/microsoft-edge/devtools-guide-chromium/evaluate-performance/