Next.js 和 Gatsby 中新版 Web Pack 分塊策略可盡量減少重複程式碼,以改善網頁載入效能。
Chrome 採用各種工具和協作功能 導入了 JavaScript 開放原始碼生態系統的架構最近有多項新的最佳化項目 ,改善 Next.js 的載入效能 「Gatsby」Gatsby。本文介紹改良的精細分塊策略 ,現在這兩種架構皆預設為出貨。
簡介
和許多網路架構一樣,Next.js 和 Gatsby 使用 webpack 做為核心
Bundler。推出 Webpack 第 3 版
輸入 CommonsChunkPlugin
,即可
在單一 (或少數)「常用」中,不同進入點共用的輸出模組區塊 (或
區塊)。共用程式碼可單獨下載,並提早儲存在瀏覽器快取中,
可以提高載入效能
許多單頁應用程式架構採用了一個進入點, 如下所示:
雖然實際可行,但把所有共用的模組程式碼整合成單一區塊的概念則有其功用
至於並非每個進入點共用的模組,可下載至不使用該模組的路徑
導致下載的程式碼超過必要舉例來說,當 page1
載入時
common
區塊時,即使 page1
未使用 moduleC
,它會載入 moduleC
的程式碼。
因此,Webpack v4 的外掛程式並採用
一個:SplitChunksPlugin
。
加強組塊
「SplitChunksPlugin
」的預設設定適用於多數使用者。多個分割區塊
根據多項條件建立
防止擷取多個路線的重複程式碼。
不過,許多使用這個外掛程式的網路架構仍會遵循「單一常見」分塊的方法
舉例來說,Next.js 會產生 commons
軟體包,其中包含在
在超過 50% 的網頁和所有架構依附元件 (react
、react-dom
等) 中使用。
const splitChunksConfigs = {
…
prod: {
chunks: 'all',
cacheGroups: {
default: false,
vendors: false,
commons: {
name: 'commons',
chunks: 'all',
minChunks: totalPages > 2 ? totalPages * 0.5 : 2,
},
react: {
name: 'commons',
chunks: 'all',
test: /[\\/]node_modules[\\/](react|react-dom|scheduler|use-subscription)[\\/]/,
},
},
},
雖然將架構相依程式碼加入共用區塊中, 快取任何進入點,也就是將使用的常見模組加入超過 30 個 半個網頁的成效較差。如果修改這個比例,系統只會產生以下兩種結果:
- 如果減少比率,下載出更多不必要的程式碼。
- 如果您提高比率,則多條路線上會有更多程式碼。
為解決這個問題,Next.js 採用
對 SplitChunksPlugin
設定
不必要的程式碼。
- 所有規模夠大的第三方模組 (超過 160 KB) 都會分割成獨立的獨立模組 區塊
- 系統會為架構依附元件 (
react
、react-dom
和frameworks
依此類推) - 您可以視需要建立共用區塊 (最多 25 個)
- 要產生的區塊大小下限變更為 20 KB
這種精細的區塊化策略具有下列優點:
- 縮短網頁載入時間。發出多個共用區塊,而非單一區塊 盡可能減少任何進入點不需要 (或重複) 的程式碼。
- 改善導覽期間的快取功能。分割大型程式庫和架構依附元件 分為多個獨立區塊,可降低快取撤銷的可能性,因為兩者不太可能 直到升級為止
您可以在 webpack-config.ts
中查看 Next.js 採用的完整設定。
更多 HTTP 要求
SplitChunksPlugin
定義了精細分塊的基礎,並將此方法套用至
像 Next.js 這樣的架構並不是全新的概念然而,許多架構仍持續
使用單一經驗法則有幾個原因當中包含
HTTP 要求都可能會對網站效能造成負面影響。
瀏覽器只能向單一來源建立有限數量的 TCP 連線 (Chrome 為 6 個),因此 盡量減少套裝組合輸出的區塊數量,可確保要求總數 低於這個門檻不過,這個情況僅適用於 HTTP/1.1。HTTP/2 中的多工處理 可讓系統以單一連線,在單一連線時,並行串流多項要求 來源。換句話說,我們通常不需要擔心區塊數量 發出的訊息。
所有主要瀏覽器都支援 HTTP/2。Chrome 與 Next.js 團隊敬上
,想看看能否分割 Next.js 的單一「commons」來增加要求數量區域組合
分為多個共用區塊,無論如何都會影響載入效能。他們一開始先測量
以及使用
maxInitialRequests
敬上
資源。
一個網頁上平均有三次測試
load
、
start-render
改變初始顯示時間上限時,First Contentful Paint 都不會改變
要求數量 (從 5 至 15 個)。有趣的是,我們注意到應用程式效能負擔略微
必須積極分割成數百個要求
這證明瞭如果比率維持在可靠的門檻 (20 至 25 個要求) 內,就獲得足夠的平衡
介於載入效能與快取效率之間經過一些基準測試後,獲選為 25 項
maxInitialRequest
計數。
修改同時發生的請求數量上限,導致產生超過一次 共用套件,並且為每個進入點妥善分隔,大幅降低 相同網頁上不需要的程式碼
這項實驗只是為了修改請求數量,以便瞭解是否有
對網頁載入效能的負面影響結果顯示,將 maxInitialRequests
設為
測試頁面上的 25
是最佳選擇,因為這樣既能減少 JavaScript 酬載大小,又不會拖慢速度
下方。等待網頁保持可用狀態所需的 JavaScript 總數
這也解釋了為何網頁載入效能不見得能改善
或大量程式碼
webpack 以 30 KB 做為產生區塊的預設大小下限。不過,將
改為將 maxInitialRequests
值設為 25,大小下限為 20 KB,這樣才能提高快取效能。
透過精細區塊縮減大小
許多架構 (包括 Next.js) 都依賴用戶端轉送 (由 JavaScript 處理) 來注入 較新的指令碼標記。但他們如何在建構期間預先決定這些動態區塊?
Next.js 會使用伺服器端的建構資訊清單檔案,判斷要使用的輸出區塊 不同的進入點為一併提供這項資訊給用戶端,是經過橋接的用戶端 建構資訊清單檔案來對應每個進入點的所有依附元件。
// Returns a promise for the dependencies for a particular route
getDependencies (route) {
return this.promisedBuildManifest.then(
man => (man[route] && man[route].map(url => `/_next/${url}`)) || []
)
}
這項新的精細分段策略最初是在 Next.js 中推出,在標記背後經過測試, 早期採用者人數許多 JavaScript 整合讓他們使用的 JavaScript 總數大幅減少 整個網站:
網站 | JS 總變化 | 差異百分比 |
---|---|---|
https://www.barnebys.com/ | -238 KB | -23% |
https://sumup.com/ | -220 KB | -30% |
https://www.hashicorp.com/ | -11 MB | -71% |
最終版本預設為 9.2 版。
Gatsby
Gatsby 用於遵循與用量導向的相同方法 定義常見模組的經驗法則:
config.optimization = {
…
splitChunks: {
name: false,
chunks: `all`,
cacheGroups: {
default: false,
vendors: false,
commons: {
name: `commons`,
chunks: `all`,
// if a chunk is used more than half the components count,
// we can assume it's pretty global
minChunks: componentsCount > 2 ? componentsCount * 0.5 : 2,
},
react: {
name: `commons`,
chunks: `all`,
test: /[\\/]node_modules[\\/](react|react-dom|scheduler)[\\/]/,
},
透過針對 Webpack 設定進行最佳化調整,來採用類似的精細分塊策略,他們也成功 我們發現,許多大型網站大幅縮減 JavaScript:
網站 | JS 總變化 | 差異百分比 |
---|---|---|
https://www.gatsbyjs.org/ | -680 KB | -22% |
https://www.thirdandgrove.com/ | -390 KB | -25% |
https://ghost.org/ | -1.1 MB | -35% |
https://reactjs.org/ | -80 KB | -8% |
請參閱 PR 以瞭解其運作方式 將這個邏輯實作至他們的 webpack 設定中,而在 v2.20.7 版中預設會發布該設定。
結論
運送精細區塊的概念並非 Next.js、Gatsby 或 Webpack 專用。適合所有人 建議改善應用程式的分段策略,只要遵循 組合方法。
- 如果你想看到將相同的區塊化最佳化設定套用到香草 React 應用程式, 來看看這個 React 範本範例 app。該公式採用 簡化版精細分塊策略,有助您開始以 定義不同類型的邏輯
- 以匯總作業來說,系統會依預設以精細的方式建立區塊。查看以下指標
manualChunks
(如要手動新增) 設定行為