透過共用字典大幅提升壓縮效率

發布日期:2024 年 3 月 6 日

資料壓縮是經過時間考驗的效能最佳化技術,可縮減符合條件的網頁資源大小。有一段時間,網頁伺服器普遍會主要使用 gzip 壓縮常見的網頁文字資源 (例如 HTML、CSS 和 JavaScript 檔案),然後傳送至用戶端進行解壓縮。這樣一來,資源載入速度會更快,但網頁的預期行為不會受到影響。

雖然 gzip 本身就非常有效,但近年來網頁壓縮技術又有了進一步的改良。2016 年,Chrome 推出 Brotli 演算法,為符合資格的資源提供整體更佳的壓縮率。到了 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 版做為字典,壓縮 1.8.3 版的 Angular,輸出內容會略高於 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.*.cssUse-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-dzstd-d 權杖。這時系統會套用標準壓縮流程。

動態資源的共用字典壓縮

動態資源也能受益於共用字典壓縮。動態資源會根據情境而變更,例如新聞網站的主要頁面會隨著新聞事件更新。HTML 文件通常是動態資源。在這種情況下,字典可以包含網站的大部分常見 HTML 結構和範本程式碼,進而壓縮網頁,只傳送每個網頁的獨特部分。

由於動態產生的資源性質,字典必須載入用戶端,以供日後使用。預先載入字典表示對動態資源套用共用字典壓縮是推測性的。在這種情況下,我們希望網站能獲得足夠的流量,讓字典成本可攤銷至大量導覽。如果您決定試用,第一步是在網頁 HTML 中,透過 <link> 元素指定字典位置:

<link rel="dictionary" href="/dictionary.dat">

Chrome 遇到這個 <link> 元素時,可能會在網頁閒置時擷取字典,並以低優先順序執行,盡量避免頻寬爭用。字典本身的回應必須指定 Use-As-Dictionary 標頭,並指定適用的動態資源路徑:

Use-As-Dictionary: match="/product/*"

從這裡開始,流程與靜態資源大致相同。瀏覽器會發現字典本身適用於相符的資源,並將 Available-Dictionary 標頭附加至要求,其中包含字典內容的雜湊值,這與稍早說明的靜態資源流程類似。

在建構時壓縮靜態資源

如果您熟悉套件組合工具,可能也知道這類工具的各種外掛程式,可在建構時壓縮資源,然後提供壓縮後的資源。舉例來說,Apache 可讓您使用指令,在要求時提供這些預先壓縮的資源

大多數支援壓縮的 Node.js 型打包工具,都會使用 Node 的內建 Zlib 程式庫。Zlib 支援 Brotli,而使用 Zlib 的打包工具通常會提供介面,可將選項直接傳遞至 Zlib,支援字典輔助壓縮。以下列舉幾個支援使用字典的打包工具:

請注意,資源任何版本的可用字典都可能使用資源的任一舊版。也就是說,您需要分析使用者流量,並據此規劃。盡量兼顧平衡,並生成可讓最多回訪使用者受益的資源。CDN 供應商目前正在測試共用字典壓縮功能。目前尚未提供公開實作項目,但我們預期情況會有所改變!

快來體驗看看吧!

整合共用字典壓縮與瀏覽器現有的壓縮功能,可大幅提升網站的載入效能,特別是經常發布更新版正式程式碼,且回訪者流量顯著的網站。如要試試共用字典壓縮功能,有兩種做法:

  1. 如果您只是想自行調整共用字典壓縮功能,瞭解運作方式,可以在 chrome://flags 頁面啟用「壓縮字典傳輸」實驗功能。
  2. 如果您有興趣在正式版網站上試用這項功能,並瞭解共用字典壓縮功能如何造福實際使用者,請註冊原始碼試用計畫以取得權杖,並詳閱原始碼試用計畫的運作方式

結論

我們對這項網路壓縮技術的重大進展感到非常興奮,因為這項技術可大幅提升使用者日常應用程式的執行速度。歡迎試用,最重要的是,我們很想知道你的想法!如果發現錯誤,請前往 crbug.com 回報。如需其他資源和工具,請造訪 use-as-dictionary.com。最後,如果您想深入瞭解運作方式,建議閱讀說明