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

資料壓縮是經過時間考驗的效能最佳化技術,可縮減符合資格的網頁資源大小。一段時間以來,一般做法都是在網路伺服器上主要使用 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.*.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 標頭至要求,其中包含字典內容的雜湊,這與先前說明的靜態資源流程類似。

在建構期間壓縮靜態資源

如果您熟悉 Bundler,可能也熟悉各種 Bundler 外掛程式,這些外掛程式可在建構期間壓縮資源,並隨後提供這些壓縮資源。舉例來說,Apache 可讓您在要求時使用指令來提供這些預先壓縮的資源

大多數支援壓縮功能的 Node.js 系別包裝程式都會使用 Node 內建的 Zlib 程式庫。Zlib 支援 Brotli,而使用 Brotli 的 bundler 通常會提供介面,可將選項直接傳遞至 Zlib,後者支援字典輔助壓縮。以下是幾個支援使用字典的 bundler:

請注意,任何資源的特定版本可用的字典,可能會使用任一舊版資源的字典。也就是說,您需要分析使用者流量並據此規劃。請盡可能取得平衡,並產生能盡可能吸引最多回訪使用者的資源。CDN 供應商目前正在實驗共用字典壓縮功能。目前尚未有任何實作項目可供大眾使用,但我們希望這項情況能有所改變!

快來體驗看看吧!

對於經常發布更新的正式版程式碼,並從回訪訪客獲得大量流量的網站,整合共用字典壓縮功能和瀏覽器現有的壓縮功能,可能會大幅改善網站的載入效能。如果您想試試共用字典壓縮功能,有兩種方法可供選擇:

  1. 如果您只是想自行調整共用字典壓縮功能,瞭解其運作方式,可以在 chrome://flags 頁面上啟用 壓縮字典傳輸實驗功能。
  2. 如果您想在正式網站上試用這項功能,並瞭解共用字典壓縮功能如何為實際使用者帶來好處,請註冊原始試用版以取得權杖,並參閱原始試用版的運作方式

結論

我們非常期待網路上的壓縮技術有重大突破,以及這項技術能讓使用者每天使用的現有應用程式加快多少速度。我們鼓勵您試用這項功能,最重要的是,我們希望聽聽您的想法!如果發現錯誤,請前往 crbug.com 回報。如需其他資源和工具,請造訪 use-as-dictionary.com。最後,如果您想深入瞭解所有運作方式,說明文件是下一個不錯的參考資料!