本節內容源自以下連結的內容,並受 CC BY 4.0 授權條款約束。
除非另有說明,否則以下內容可假設為基於原始內容修改和刪除的結果。
Rspack 支援程式碼分割,允許將程式碼分割成其他區塊。您可以完全控制產生資源的大小和數量,這讓您在載入時間方面獲得效能提升。
在這裡,我們引入一個稱為 Chunk 的概念,它表示瀏覽器需要載入的資源。
Rspack 使用符合 ECMAScript 動態導入提案的 import() 語法。
Rspack 不支援 require.ensure
。
在 index.js
中,我們透過 import()
動態導入兩個模組,從而分離成一個新的區塊。
現在我們建置此專案,我們會得到 3 個區塊,src_bar_js.js
、src_foo_js.js
和 main.js
,如果您看到它們,您會發現 shared.js
同時存在於 src_bar_js.js
和 src_foo_js.js
中,我們將在後續章節中移除重複的模組。
雖然 shared.js
存在於 2 個區塊中,但它只會執行一次,您不必擔心多個實例的問題。
這是分割程式碼最簡單且最直覺的方式。但是,這種方法需要我們手動配置 Rspack。讓我們從研究如何從多個進入點分割多個區塊開始。
這將產生以下建置結果
同樣地,如果您檢查它們,您會發現它們都包含重複的 shared.js
。
上面提到的程式碼分段非常直觀,但大多數現代瀏覽器都支援並行網路請求。如果我們將 SPA 應用程式的每個頁面劃分為單一區塊,並且當使用者切換頁面時,他們請求一個較大的區塊,這顯然沒有充分利用瀏覽器處理並行網路請求的能力。因此,我們可以將區塊分解成更小的區塊。當我們需要請求此區塊時,我們會同時請求這些較小的區塊,這將使瀏覽器的請求更有效率。
Rspack 預設會分割 node_modules
目錄中的檔案和重複的模組,將這些模組從它們的原始區塊提取到一個單獨的新區塊中。那麼為什麼我們的範例中的 shared.js
仍然在多個區塊中重複出現呢?這是因為我們範例中的 shared.js
大小非常小。如果將一個非常小的模組分割成一個單獨的區塊供瀏覽器載入,實際上可能會減慢載入過程。
我們可以將最小分割大小設定為 0,以允許單獨提取 shared.js
。
當重新建置時,您會發現 shared.js
已被單獨提取,並且產品中還有一個額外的區塊包含 shared.js
。
我們可以指定某些模組強制分組到單一區塊中,例如,以下配置
透過以上配置,所有路徑中包含 some-lib
目錄的檔案都可以提取到一個名為 lib
的單一區塊中。如果 some-lib
中的模組很少變更,則此區塊將持續命中使用者的瀏覽器快取,因此像這樣經過深思熟慮的配置可以提高快取命中率。
但是,將 some-lib
分隔為獨立的區塊也可能會有缺點。假設一個區塊僅依賴 some-lib
中非常小的檔案,但由於 some-lib
的所有檔案都分割為單一區塊,因此此區塊必須依賴整個 some-lib
區塊,導致載入量較大。因此,當使用 cacheGroups.{cacheGroup}.name 時,需要仔細考慮。
這裡有一個範例顯示 cacheGroup 的 name
配置的效果。
在宣告導入時使用這些內聯指示詞,允許 Rspack 輸出「資源提示」,告知瀏覽器對於
一個範例是具有 HomePage
元件,其呈現 LoginButton
元件,然後在點擊後按需載入 LoginModal
元件。
這將導致 <link rel="prefetch" href="login-modal-chunk.js">
附加在頁面的 head 中,這將指示瀏覽器在閒置時間預先擷取 login-modal-chunk.js
檔案。
Rspack 將在父區塊載入後新增預先擷取提示。
與預先擷取相比,預先載入指示詞有許多差異
一個範例可以是具有一個 Component
,其始終依賴應位於單獨區塊中的大型程式庫。
讓我們想像一個 ChartComponent
元件,其需要一個大型 ChartingLibrary
。它在呈現時會顯示一個 LoadingIndicator
,並立即按需導入 ChartingLibrary
當請求使用 ChartComponent
的頁面時,也會透過 <link rel="preload">
請求 charting-library-chunk。假設 page-chunk 較小且完成速度較快,則頁面將顯示 LoadingIndicator
,直到已請求的 charting-library-chunk
完成。由於它只需要一次來回行程而不是兩次,這將稍微縮短載入時間。尤其是在高延遲環境中。
不正確地使用 webpackPreload 實際上可能會損害效能,因此使用時請務必小心。
有時您需要自行控制預載。例如,任何動態引入的預載都可以透過非同步腳本完成。在串流伺服器端渲染的情況下,這會很有用。
如果腳本載入在 Rspack 自行開始載入該腳本之前失敗(如果該腳本不在頁面上,Rspack 會建立一個 script 標籤來載入其程式碼),則該 catch 處理常式將不會啟動,直到 chunkLoadTimeout 超時。這種行為可能令人意想不到。但這是可以解釋的 — Rspack 無法拋出任何錯誤,因為 Rspack 不知道腳本失敗了。Rspack 將會在錯誤發生後立即為該腳本添加 onerror 處理常式。
為了避免這種問題,您可以添加自己的 onerror 處理常式,在發生任何錯誤時移除該腳本。
在這種情況下,出錯的腳本將被移除。Rspack 將建立自己的腳本,並且任何錯誤都將在沒有超時的情況下被處理。