[譯] 一行 JavaScript 代碼居然讓 FT.com 網站慢了十倍

性能退化的探索之旅

發現問題

這一切開始於一個警報,首頁應用的錯誤率高於 4% 的閾值。javascript

顯示數千個錯誤頁面對咱們的用戶產生了切實的影響(還好 CDN 緩存抵消一部分影響)。html

被用戶看到的錯誤頁面前端

應用程序的錯誤日誌顯示,該應用程序沒有任何有關 top stories 的數據。java

診斷問題

首頁的工做原理是在一個時間間隔內輪詢 GraphQL api 以獲取數據,將該數據存儲在內存中並根據請求渲染它。從理論上講,若是請求失敗,應該保留以前穩定的數據。進一步深刻日誌,咱們看到對 GraphQL api 的請求失敗了,可是是有錯誤而不是超時——或者至少是不一樣類型的超時。node

FetchError: response timeout at https://….&source=next-front-page over limit: 5000
複製代碼

奇怪的是,API 的響應時間彷佛遠低於首頁設置的 5 秒超時。這讓咱們相信問題出如今首頁和應用程序之間的鏈接上。咱們作了些嘗試——在二者之間使用 keepAlive 鏈接,分散請求,這樣它們就不會同時發起。這些彷佛都沒有產生任何影響。android

更神祕的是 Heroku 上顯示的響應時間。第 95 百分位數約爲 2-3 秒,而最大值有時達到 10-15 秒。因爲首頁被 Fastly 高度緩存,包括 stale-while-revalidate 頭,許多用戶可能不會注意到。但這很奇怪,由於首頁真的不該該作不少工做來渲染頁面。全部數據都保存在內存中。ios

首頁的 Heroku 響應時間git

所以咱們決定對本地運行的應用程序副本進行一些分析。咱們將經過使用 Apache Bench 每秒發出10個請求,共發出 1000 個請求來複制一些負載。github

ab -n 1000 -c 10 http://local.ft.com:3002/
複製代碼

使用 node-clinicnsolid,咱們能夠對內存、CPU 和應用程序代碼有更深的理解。運行它們,確認咱們能夠在本地復現該問題。首頁須要 200-300 s 才能完成測試,超過 800 個請求不成功。相比之下,在文章頁面上運行相同的測試須要大約 50 秒。後端

測試用時:305.629 秒
完成的請求:1000
失敗的請求:876
複製代碼

並且你看,n-solid 的圖表顯示事件循環的滯後超過 100 毫秒。

在作加載測試時事件循環滯後

使用 n-solid 的 CPU 分析器,咱們能夠精肯定位阻塞事件循環的確切代碼行。

火焰圖顯示致使滯後的函數

修復問題

罪魁禍首是...

return JSON.parse(JSON.stringify(this._data));
複製代碼

對於每一個請求,咱們使用 JSON.parse/stringify 來建立數據的深克隆。這種方法自己不壞 —— 多是深克隆比較快方法之一。但它們是同步方法,所以在執行時會阻塞事件循環。

在咱們的案例中,這個方法在每一個頁面渲染(對於每一個被渲染的部分)中屢次調用,具備大量數據(每次執行時整個頁面所需的數據),而且咱們有幾個併發請求。因爲 Javascript 是單線程的,所以這將對應用程序嘗試執行的全部其餘操做產生連鎖反應。

深克隆數據的緣由是,咱們會根據請求中的一些信息(例如,是否啓用了特定功能的切換),來改變對象。

爲了解決這個問題——並減輕克隆全部內容的須要——咱們在檢索時對對象應用了深度凍結,而後在數據被改動的地方克隆特定位。這仍然執行同步克隆——但僅限於更小的數據子集。

結論

修復好後,咱們從新運行了負載測試,並在很短的時間內完成,0 次錯誤。

測試用時:37.476 秒
完成的請求:1000
失敗的請求:0
複製代碼

咱們發佈了修復程序,看到響應時間和錯誤(🤞🏼)當即減小,並但願一些用戶開心!

修復後首頁的響應時間

關於將來

  • 對其餘一些應用程序運行此分析,並瞭解咱們能夠進一步優化和/或減小 dyno 大小,這也會頗有趣。
  • 咱們可讓事件循環更可見嗎?
  • 咱們的首頁應該是 stale-on-error——因此爲何仍然會看到數以千計的錯誤頁面?這個數字好仍是壞?

感謝 Samuel Parkinson 的付出。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索