vite首次啟動載入慢

背景

隨著vue3的到來,vite開始被各大vue3組件庫使用,公司開始一個新項目,準備嘗試用vite試一波。

問題發現

當把公司新項目移植到vite後,啟動非常快,但發現頁渲染時間慢了很多

可以看到頁面的首屏載入時間是3.34s,頁面的渲染完時間是3.37s,下載總大小是8.6MB,發送了119個請求

在看看webpack的渲染時間:

可以看到頁面的首屏載入時間是1.05s,頁面的渲染完時間是1.21s,下載總大小是3.6MB,發送了32個請求

vite的首屏載入時間是webpack的三倍,下載文件大小是webpack的兩倍,請求數量也是三倍。vite開發環境下,模組以原生 esm 的形式被瀏覽器載入,也就說模組的載入是用es6原生的模組載入機制,沒有對程式碼進行打包壓縮處理,所以服務啟動很快。那帶來的問題就是下載的js文件沒有處理的過的源碼,那文件大小自然要比webpack處理過的js文件大很多。

 

因此初步判斷因為這個原因導致首屏載入時間相差這麼多。得出結論vite是犧牲了頁面首次載入時間來達到啟動時間快的目的。

峰迴路轉

於是我去網上尋找有沒有好的解決方案,在vite的issue中找到類似的問題:

尤大大也回答了這個問題

這個問題有兩個細節:

  1. 項目啟動後瀏覽器第一次載入才會慢。
  2. 這個慢是因為載入less的源碼,按需編譯中載入時間其實是在less的編譯上。

看看vite項目第二次載入

可以看到頁面的首屏載入時間是1.04s,頁面的渲染完時間是1.09s,下載總大小是8.6MB,發送了120個請求

頁面的渲染時間和webpack項目的渲染時間差不多,esm 的形式被瀏覽器載入和請求數量對頁面的渲染時間的影響不是主要的,也證實項目啟動後瀏覽器第一次載入多出的時間主要是在編譯上。

尤大大在知乎回答中提到:「webpack 的打包模式在項目本身源碼模組數量極大 (>1000) 的情況下還是有一點優勢的,因為瀏覽器在處理這個級別的並發請求上會產生阻塞(但通常來說如果你一個路由下模組數到這個級別說明你程式碼分割/按需載入沒做好)。」意思是esm 的形式被瀏覽器載入和請求數量對頁面的渲染時間的影響不是主要的。

分析

瀏覽器第一次載入時間比較長的文件時間分部:

 

waterfall性能檢測詳解詳解:

  • Queueing 是排隊的意思
  • Stalled 是阻塞 請求訪問該URL的主機是有並發和連接數限制的,必須要等之前的執行才能執行之後的,這段時間的耗時
  • DNS Lookup 是指域名解析所耗時間
  • Initial connection 初始化連接時間,這裡一般是TCP 3次連接握手時間
  • SSL https特有,是一種協議
  • Request sent 發送請求所消耗的時間
  • Waiting 等待響應時間,這裡一般是最耗時的
  • Content Download 下載內容所需要消耗的時間

載入index.less的時間主要在Waiting階段,Content Download的時間佔比很少。等待響應時間應該就是vite在編譯的時間。

我的項目也引用了組件庫的less源碼,改為引用組件庫的css看下渲染時間如何

可以看到頁面的首屏載入時間是1.13s,頁面的渲染完時間是1.16s,下載總大小是8.4MB,發送了120個請求

渲染速度基本和webpack差不多。

結論

通過上面分析可以確定vite開發模式啟動,頁面載入慢的原因是less編譯導致。

這裡反思下,由於對調試工具waterfall性能檢測不熟悉導致開始錯誤的結論,走了一下彎路。有時候我們通過理論推導出來的結論未必正確的,需要實際數據去證實但更需要去證偽。就像吳軍老師說的:

「我們每次給出的結論,都存在一種證偽的可能性,我們可以設計出一種方法、一個實驗,或者一個場景,去看看我們的結論是不是還是成立,如果成立,我們就維持現有的結論;如果不成立,我們就修改現有結論。這就叫做證偽。

科學是一種做事情的方法,而不是特定的結論。採用科學方法得到的結論,相對來講,比較經得起時間和現實世界的檢驗。更重要的是,用科學的方法求知,我們能得到可累加的進步,因為每一次驗證的過程都是可以重複,後面的工作也可以基於前面的工作展開。」這句話牢記心中。

Tags: