發現性能問題
上一次導入數據后,發現系統十分的卡頓,但是才僅僅1000多條數據而已,怎么會讓系統變得如何的卡頓呢?於是我開始走在排查系統卡頓的原因的道路上。
首先,先定位問題是出現在前端上還是后端上。打開瀏覽器,輸入localhost:7000
, 然后F12打開netword。啟動后端項目,查看log。切換回瀏覽器,右鍵刷新。結果發現好多些問題:
- 請求發送的個數比較多。
- 后端每個接口的響應時間都比較長,都超過了1s,這明顯有問題。
- 前端很多請求從: 發送請求到頁面渲染成功所需要的時間大於了10S(發送請求時間+后端接口響應時間+下載資源時間,即回傳數據時間+頁面渲染時間)。
從上面這幾個現象可以看出:
- 后端有明顯的問題。
- 前端暫時沒有什么問題。
好好分析一下,為什么后端每個接口的響應時間都會超過1s,mongodb是出了名的速度快,一般查詢數據就幾十ms,普通查詢也不會超過300ms。但是看到的接口響應時間卻是超過了1s,有的還是明顯3,4s。
苦苦冥想,細細推測,思來想去,都不知道是怎么回事,最后只有采用刪代碼的方式來定位問題了。
當刪除類似於下面的代碼的時候
Schema.virtual('affixes', {
ref: 'Affix',
localField: '_id',
foreignField: 'businessId',
});
這個時候,發現后端接口的響應時間正常了,可以判斷,這段代碼起到了一定的作用,但是這只是簡單的連表查詢而已。為什么就導致接口響應時間多那么多呢?
我繼續分析,進入到controller.js里面,將與表關聯查詢的代碼找出來,終於,我快要發現元凶了,刪除這幾行代碼,ok,同樣,響應時間正常了。
仔細分析這幾行代碼,發現了一個很重要的事情: 居然是全表查詢!!而且是3張表關聯的全表查詢!!所以...查詢的數據差不多就是這個量: 2000 * 2000 * 2000, 也怪不得為什么響應時間會超出1s了。
第一個元凶已經被抓住了。但是我還並不知道為什么前端從請求到渲染成功的時間怎么會超過10s,這簡直不能忍。
清空network,然后刷新,重新發送請求,可以看見發送了5個左右的請求,而查看后端的log發現其中3個請求都是在做表關聯的全表查詢,並且reply的時候還是將所有的數據都返回到前端里去了。
ok,現在我大概已經知道為什么會有超過10s的響應時間了,下載的數據量也比較大,所以響應時間 = 發送請求時間 + 后端處理時間 + 下載資源時間 + 渲染時間, 由於數據量比較大,所以導致最后的兩個時間也不小。
現在大概已經都找出了為什么頁面會卡頓並且遲緩。原因就是沒有做后端分頁,系統里用的是前端分頁。
性能優化總結
- 查詢數據避免多張表關聯全表查詢。
- 先過濾再關聯查詢,而不是先查詢再關聯表。
- react里多個列表,一定要設置key。
- 分頁一定不要前端做,因為數據量大了肯定要崩掉的。