資料壓縮是經過時間考驗的效能最佳化技術,可縮減符合資格的網頁資源大小。一段時間以來,一般做法是在網路伺服器上主要使用 gzip 壓縮常見的文字型網頁資源,例如 HTML、CSS 和 JavaScript 檔案,然後將這些檔案傳送至可解壓縮的用戶端。這樣一來,資源的載入時間就能加快,且不會影響網頁的預期行為。
雖然 gzip 本身就非常有效,但近幾年網頁壓縮技術已獲得進一步改善。2016 年,Brotli 演算法在 Chrome 中推出,為符合條件的資源提供整體更佳的壓縮率。截至 2017 年底,所有新式瀏覽器都支援 Brotli,且伺服器的支援範圍也開始擴大。近期,Chrome 已推出 ZStandard 壓縮功能。
但這項工作並未就此結束!Chrome 團隊一直致力於讓共用字典可在網路上使用,目前 Brotli 和 ZStandard 的原始試用版都已支援這項功能。共用字典可補足 Brotli 和 ZStandard 壓縮功能,為經常發布更新程式碼的網站提供更高的壓縮率,在某些情況下,甚至可達 90% 以上的壓縮率。這篇文章將進一步說明共用字典的運作方式,以及如何註冊原始試用版,以便在網站上使用 Brotli 和 ZStandard。
共用字典說明
壓縮是指在輸入內容中找出重複的序列,並使用該資訊建立更小的輸出內容,以便日後反轉。壓縮功能在網路上運作良好,因為它可大幅縮短資源載入時間。Brotli 和 ZStandard 都能使用壓縮字典進一步提高效能,這項字典是這些演算法在壓縮期間可使用的額外模式集合。事實上,Brotli 的高度效率在某種程度上是透過使用內部字典而達成。
不過,您可以使用自訂的使用者編輯字典,搭配包含特定資源專屬模式的 Brotli 和 ZStandard。實際上,自訂字典是外部檔案,可套用至任何輸入內容。字典可以非常明確地指出應用程式的正式版程式碼,或任何內容。特定字典與輸入內容的適用程度,可能會對整體壓縮效率造成重大影響。與輸入內容高度相似的字典,產生的輸出內容壓縮率會高於一般或不相似內容的字典。
以下提供一個自訂壓縮字典的有效範例:假設您的網站使用 Angular 架構,且目前使用的版本為 1.7.9。這個版本的 Angular 架構在未壓縮的情況下約為 172 KiB。使用 Brotli 的預設設定進行壓縮後,大小約為 53 KiB。壓縮比率可達到 70%。不過,假設您之後決定升級至 Angular 1.8.3,由於這個版本的 Angular 大小與 1.7.9 版本大致相同,因此壓縮率也與先前版本大致相同。
這時自訂字典就派上用場,可使用稱為差分壓縮的程序,也就是使用舊版資源的字典來壓縮較新版本。以上述範例為例,如果您使用 1.7.9 版做為字典,壓縮 Angular 1.8.3 版,輸出結果會略大於 4 KiB。這代表壓縮率為 近 98%。很明顯,壓縮字典對載入效能有重大影響,而且在實際應用中已證明其有效性!
不過,要讓這個流程在網路上運作,有一定的難度。不過,如果您使用字典壓縮資源,就必須使用相同的字典才能解壓縮。我們先前曾嘗試在網路上實作這項流程 (即 SDCH),但難以安全地導入。這項最新的共用字典壓縮提案解決了這些疑慮,同時為靜態和動態資源提供實質的效益。
Chrome 如何宣傳支援共用字典
所有瀏覽器都會透過 Accept-Encoding
要求標頭宣告支援的壓縮演算法。標頭內容是以半形逗號分隔的支援編碼清單:
Accept-Encoding: gzip, br, zstd
這個特定的 Accept-Encoding
標頭指出,要求資源的瀏覽器支援 gzip、Brotli 和 ZStandard 壓縮演算法。回應要求的網頁伺服器就能決定要使用哪種演算法回應要求。
啟用共用字典支援功能,並為資源提供相關字典後,系統會在 Accept-Encoding
標頭中新增額外符記。這些符記分別是 Brotli 的 br-d
和 Zstandard 的 zstd-d
。Chrome 也會納入可用字典的雜湊值,我們會在後續章節說明。
Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:
如果網路伺服器已設定為辨識這個符記,且能辨識字典,則可使用適用的編碼,以字典壓縮的資源回應該要求。實際上如何實現這項功能,取決於要求是針對靜態資源還是動態資源。
針對靜態資源使用共用字典壓縮功能
靜態網頁資源會一律為要求的網址產生相同回應。可壓縮的靜態網頁資源常見例子包括 JavaScript 和 CSS 檔案。這些資源通常會以某種方式進行版本控制,以利快取。有時會在檔案名稱中加入檔案內容的雜湊 (例如 styles.abcd1234.css
),或是使用其他方法來建立資源的指紋。這些資源類型非常適合使用共用字典提供的差異壓縮功能,因為靜態資源通常會長時間快取,且經常更新。
您可以為靜態資源設定 Use-As-Dictionary
回應標頭,藉此指定字典。標頭會採用其中一個鍵/值組合,但唯一必要的組合是 match
,它會接受 URLPattern
語法,指定應使用字典的資源路徑:
Use-As-Dictionary: match="/dist/styles.*.css"
您可以將 Use-As-Dictionary
標頭視為一種機制,適用於日後與其中指定模式相符的資源版本。舉例來說,假設您的網站會在單一 CSS 檔案中提供所有樣式。為簡化說明,假設該資源的第一個版本位於 /dist/styles.v1.css
,且會透過含有 match
值為 /dist/styles.*.css
的 Use-As-Dictionary
回應標頭傳送。
一段時間後,您更新網站的 CSS,並發布位於 /dist/styles.v2.css
的新版本。由於先前版本 Use-As-Dictionary
回應標頭中使用的 match
值適用於此要求,因此瀏覽器會傳送 Available-Dictionary
標頭,其中包含以 結構化欄位位元組序列編碼的字典雜湊:
Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:
此時,由伺服器負責設定壓縮功能,確保使用相符的字典。系統會傳送使用該字典壓縮的資源,並使用使用者瀏覽器快取中可用的字典進行解壓縮。
如果您經常為網站發布新程式碼,差異壓縮功能就能發揮很大的作用。不過,這項程序相當彈性。如果瀏覽器無法判斷使用者的瀏覽器快取中是否有字典,就不會在 Accept-Encoding
標頭中指定額外的 br-d
或 zstd-d
符記。在這種情況下,系統會套用標準壓縮流程。
動態資源的共用字典壓縮功能
動態資源也可以從共用字典壓縮中受益。動態資源會根據情境變更,例如新聞網站的主頁面會隨著新聞動態頻繁更新。HTML 文件通常是動態資源。在這種情況下,字典可包含網站的大部分常見 HTML 結構和範本程式碼,進而產生壓縮的網頁,只傳送每個網頁的專屬部分。
由於動態產生的資源具有特殊性,因此必須在用戶端上載入字典,以便日後使用。提前載入字典,表示將共用字典壓縮功能套用至動態資源是推測性的。在這種情況下,我們希望網站能獲得足夠的流量,讓字典成本可攤銷在大量導覽中。如果您決定嘗試,第一步是透過網頁 HTML 中的 <link>
元素指定字典位置:
<link rel="dictionary" href="/dictionary.dat">
當 Chrome 遇到這個 <link>
元素時,可能會在網頁閒置時以低優先順序擷取字典,以免發生頻寬爭用情形。字典本身的回應必須指定 Use-As-Dictionary
標頭,並指定所適用的動態資源路徑:
Use-As-Dictionary: match="/product/*"
從這裡開始,流程與靜態資源大致相同。瀏覽器會看到字典本身套用於相符的資源,並附加 Available-Dictionary
標頭至要求,其中包含字典內容的雜湊,這與先前說明的靜態資源流程類似。
在建構期間壓縮靜態資源
如果您熟悉 Bundler,可能也熟悉各種 Bundler 外掛程式,這些外掛程式可在建構期間壓縮資源,並隨後提供這些壓縮資源。舉例來說,Apache 可讓您在要求時使用指令來提供這些預先壓縮的資源。
大多數支援壓縮功能的 Node.js 系別包裝程式都會使用 Node 內建的 Zlib 程式庫。Zlib 支援 Brotli,而使用 Brotli 的 bundler 通常會提供介面,可將選項直接傳遞至 Zlib,後者支援字典輔助壓縮。以下是幾個支援使用字典的 bundler:
- 透過
compressionOptions
介面,使用 webpack 的CompressionWebpackPlugin
。 rollup-plugin-brotli
提供options
設定,可直接傳送至 Node.js 中的 Zlib,並在該處指定字典。- esbuild 適用的
esbuild-plugin-compress
第三方外掛程式也提供 Node.js 中的 Zlib 選項存取權。
請注意,任何資源的特定版本可用的字典,可能會使用任一舊版資源的字典。也就是說,您需要分析使用者流量並據此規劃。請盡可能取得平衡,並產生能盡可能吸引最多回訪使用者的資源。CDN 供應商目前正在實驗共用字典壓縮功能。目前尚未有可供大眾使用的實作項目,但我們希望這項情況會有所改變!
快來體驗看看!
對於經常發布更新的正式版程式碼,並從回訪訪客獲得大量流量的網站,整合共用字典壓縮功能和瀏覽器現有的壓縮功能,可能會大幅改善網站的載入效能。如果您想試試共用字典壓縮功能,有兩種方法可供選擇:
- 如果您只是想自行調整共用字典壓縮功能,瞭解其運作方式,可以在
chrome://flags
頁面上啟用 壓縮字典傳輸實驗功能。 - 如果您想在正式網站上試用這項功能,並瞭解共用字典壓縮功能如何為實際使用者帶來好處,請註冊原始試用版以取得權杖,並參閱原始試用版的運作方式。
結論
我們非常期待網路上的壓縮技術有重大突破,也期待這項技術能讓使用者每天使用的現有應用程式變得更快速。我們鼓勵您試用這項功能,最重要的是,我們希望聽聽您的想法!如果發現錯誤,請前往 crbug.com 回報。如需其他資源和工具,請造訪 use-as-dictionary.com。最後,如果您想深入瞭解所有運作方式,說明文件是下一個不錯的參考資料!