背景
隨着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中找到類似的問題:
尤大大也回答了這個問題
這個問題有兩個細節:
- 項目啓動後瀏覽器第一次加載纔會慢。
- 這個慢是因爲加載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性能檢測不熟悉導致開始錯誤的結論,走了一下彎路。有時候我們通過理論推導出來的結論未必正確的,需要實際數據去證實但更需要去證僞。就像吳軍老師說的:
“我們每次給出的結論,都存在一種證僞的可能性,我們可以設計出一種方法、一個實驗,或者一個場景,去看看我們的結論是不是還是成立,如果成立,我們就維持現有的結論;如果不成立,我們就修改現有結論。這就叫做證僞。
科學是一種做事情的方法,而不是特定的結論。採用科學方法得到的結論,相對來講,比較經得起時間和現實世界的檢驗。更重要的是,用科學的方法求知,我們能得到可累加的進步,因爲每一次驗證的過程都是可以重複,後面的工作也可以基於前面的工作展開。”這句話牢記心中。