當前位置: 妍妍網 > 碼農

Vite 5.1 正式釋出,效能大幅提升!

2024-02-08碼農

去年 11 月,Vite 5 的釋出標誌著 Vite 及其生態系再次取得了巨大的進步。而就在幾周前,我們喜迎了 npm 每周下載量突破 1000 萬次以及 Vite 倉庫貢獻者達到 900 名的裏程碑。今天,Vite 5.1 版本正式釋出了,本文就來看看該版本帶來了哪些更新!

Vite 執行時 API

Vite 5.1 引入了實驗性的 Vite 執行時 API 支持,允許透過 Vite 外掛程式處理並執行任意程式碼。與 server.ssrLoadModule 不同,新 API 的執行時實作與伺服器完全解耦,為庫和框架開發者提供了在伺服器與執行時之間實作自訂通訊層的機會。一旦穩定,該 API 有望替代 Vite 當前的 SSR 基礎元件。

這一新 API 帶來了顯著優勢:

  • 支持在 SSR 期間進行 HMR(熱更新),提升開發效率。

  • 由於與伺服器解耦,單個伺服器可支持無限量客戶端,且每個客戶端擁有獨立的模組緩存,通訊方式靈活多樣(如訊息通道、fetch 呼叫、直接函式呼叫或 WebSocket)。

  • 不依賴 node/bun/deno 等任何內建 API,因此具備跨環境執行的能力。

  • 輕松整合具有自訂執行程式碼機制的工具,例如透過提供執行器選擇使用 eval 而非 new AsyncFunction。

  • 該創意最初由 Pooya Parsa 提出,並由 Anthony Fu 以 vite-node 包的形式實作,以支持 Nuxt 3 的開發環境 SSR,並隨後成為 Vitest 的基礎。經過一段時間的實戰檢驗,Vladimir Sheremet 在 Vitest 中對 vite-node 進行了重新實作,並汲取經驗,將 API 打造得更加強大和靈活,最終整合到 Vite Core 中。這個 PR 歷時一年精心打磨,期間與生態系維護者進行了深入的討論和協作。

    新特性

    .css?url 的支持改進

    CSS 檔現在能夠以更高的可靠性和準確性作為 URL 被匯入,這一改進標誌著 Remix 遷移到 Vite 過程中的最後一道障礙的克服。

    build.assetsInlineLimit 支持回呼函式

    使用者現在能夠透過提供一個回呼函式來進一步自訂資源行內的邏輯。該回呼函式應返回一個布爾值,用以決定特定資源是否應被行內。若函式返回 undefined ,則預設邏輯將生效。

    迴圈匯入的 HMR 最佳化

    在 Vite 5.0 中,迴圈匯入中的已接受模組在發生更改時總是會觸發整個頁面的重新載入,即使這些模組在客戶端能夠無縫處理。現在,這一限制已被放寬,允許在不需重新載入整個頁面的情況下套用 HMR。然而,如果在 HMR 過程中遇到任何錯誤,頁面將重新載入以確保一致性。

    支持 ssr.external: true 實作全面外部化 SSR 包

    過去,Vite 會在伺服器端渲染(SSR)時將除已連結包外的所有包外部化。現在,透過新引入的 ssr.external: true 選項,使用者可以強制將所有包(包括已連結的包)都進行外部化處理。這一特性在單倉庫(monorepo)環境中進行測試時顯得尤為實用,因為它能模擬出所有包均被外部化的標準情況。此外,在透過 ssrLoadModule 載入任意檔時,始終將包外部化可以確保我們無需關註熱更新(HMR)的實作細節。

    預覽伺服器新增 close 方法實作優雅關閉

    為了提升預覽伺服器的管理能力,現在伺服器物件暴露了一個 close 方法。透過呼叫這個方法,使用者可以優雅地關閉伺服器,並確保所有已開啟的套接字連線都被正確關閉。這一改進有助於提升伺服器的穩定性和可維護性。

    效能提升

    隨著每次版本的叠代,Vite 都在不斷追求極致的速度。Vite 5.1 更是如此,帶來了顯著的效能改進。我們采用了 vite-dev-server-perf 工具來精準測量從 Vite 4.0 開始的所有次要版本在載入大量模組時的效能表現。測試環境包括了 10000 個模組和 25 級深度的模組樹,每個模組都是一個包含計數器和匯入其他檔的 TypeScript 檔。這樣的設定確保了測試主要聚焦於請求各個模組所需的時間。

    在 Vite 4.0 中,載入 10000 個模組在 M1 MAX 裝置上需要 8 秒。而在 Vite 4.3 中, Vite 團隊專註於效能最佳化,成功地將載入時間縮短至 6.35 秒。如今,在 Vite 5.1 中,再次實作了效能的提升。Vite 僅需 5.35 秒就能載入這 10000 個模組,比 Vite 4.0 快了近 3 秒,比 Vite 4.3 也快了近 1 秒。這些成績不僅驗證了 Vite 無捆綁方法的優勢,也彰顯了 Vite 團隊對效能持續最佳化的承諾。

    這個基準測試是在無頭 Puppeteer 上執行的,是一個比較各個版本的好方法。但它並不代表使用者實際體驗到的時間。當在 Chrome 的隱身視窗中執行相同的 10000 個模組時,得到以下結果:


    10000 模組 Vite 5.0 Vite 5.1
    載入時間 2892ms 2765ms
    載入時間 (已緩存) 2778ms 2477ms
    完全重新載入 2003ms 1878ms
    完全重新載入(已緩存) 1682ms 1604ms

    線上程中執行 CSS 預處理器

    Vite 現在支持透過多執行緒執行 CSS 預處理器,從而極大提高了處理速度。透過簡單地設定 css.preprocessorMaxWorkers: true 就可以啟用這一功能。以 Vuetify 2 計畫為例,啟用此功能後,開發啟動時間縮短了 40%。

    改進伺服器冷啟動的新策略

    對於大型計畫,引入了一個新的依賴項最佳化策略。透過設定 optimizeDeps.holdUntilCrawlEnd: false ,可以切換到這一新策略,從而可能進一步提升依賴項的處理速度。Vite 團隊正在考慮將此策略作為未來的預設設定。

    使用緩存加速解析

    為了提高解析速度,預設啟用了 fs.cachedChecks 最佳化。在 Windows 環境下,這一最佳化使 tryFsResolve 的速度提升了約 14 倍,同時在三角形基準測試中,解析 ids 的總體速度也提高了約 5 倍。

    內部效能最佳化

    Vite 的開發伺服器也在不斷地進行內部效能最佳化。引入了新的中介軟體以在 304 響應時進行短路處理,避免了在熱路徑中進行不必要的請求解析,並確保了 Rollup 的正確惰性載入。這些改進共同提升了 Vite 的整體效能。

    棄用功能

    import.meta.glob 中的 'as' 選項已被棄用

    隨著標準遷移到 Import Attributes, 'as' 選項在 import.meta.glob 中不再受支持。雖然目前不打算用新選項來替代它,但建議使用者轉而使用 query 功能。

    移除 Vite 3 中的實驗性構建時預打包功能

    在 Vite 3 中引入的實驗性構建時預打包功能現已被移除。隨著 Rollup 4 切換到原生解析器,並且 Rolldown 計畫正在積極推進中,該功能的效能以及開發和構建之間的一致性問題已不再有效。Vite 團隊致力於改進開發/構建一致性,並認為在未來使用 Rolldown 進行「開發期間的預打包」和「生產構建」是更合適的策略。Rolldown 還可能以比依賴項預打包更高效的方式實作緩存。


    往期推薦