Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 1 | # Compression Dictionary Transport |
| 2 | |
| 3 | - Contact: <compression-dictionary-transport-experiment@chromium.org> |
| 4 | - Feedback: <https://github.com/WICG/compression-dictionary-transport/issues> |
| 5 | - Chrome status: <https://chromestatus.com/feature/5124977788977152> |
| 6 | |
| 7 | ## Introduction |
| 8 | |
| 9 | This document provides an overview of the current implementation status of the |
| 10 | [**Compression Dictionary Transport**][explainer] feature in Chrome and |
| 11 | instructions on how to enable it. |
| 12 | |
| 13 | Starting from version 117, Chrome experimentally supports Compression Dictionary |
| 14 | Transport feature. This feature adds support for using designated previous |
Tsuyoshi Horo | 27c43a3f | 2023-08-22 07:36:14 | [diff] [blame] | 15 | responses, as an external dictionary for Brotli- or Zstandard-compressed HTTP |
| 16 | responses. |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 17 | |
| 18 | ## Activation |
| 19 | |
| 20 | This API can be enabled by chrome://flags or via [Origin Trial][ot-blog]. |
| 21 | |
| 22 | ### chrome://flags |
| 23 | |
| 24 | If you want to try Compression Dictionary Transport feature, you have to enable |
| 25 | both [chrome://flags/#enable-compression-dictionary-transport][flag] and |
| 26 | [chrome://flags/#enable-compression-dictionary-transport-backend][backend-flag]. |
| 27 | The details about each flag are described [here][shared_dictionary_readme]. |
| 28 | |
| 29 | ### Origin Trial |
| 30 | |
| 31 | Origin Trial token can be obtained from [the Origin Trial console][ot-console]. |
| 32 | You can enable this feature by setting `Origin-Trials` HTTP response header in |
| 33 | the page's HTML, |
| 34 | |
| 35 | ```http |
| 36 | Origin-Trial: YOUR_ORIGIN_TRIAL_TOKEN |
| 37 | ``` |
| 38 | |
| 39 | or adding a meta tag in the <header> element. |
| 40 | |
| 41 | ```html |
| 42 | <meta http-equiv="origin-trial" content="YOUR_ORIGIN_TRIAL_TOKEN"> |
| 43 | ``` |
| 44 | |
| 45 | ### Third-Party Origin Trial |
| 46 | |
| 47 | This feature supports third-party Origin Trial. If you are serving third-party |
| 48 | scripts, you can enable this feature by adding a meta tag. |
| 49 | |
| 50 | ```javascript |
| 51 | (() => { |
| 52 | const meta = document.createElement('meta'); |
| 53 | meta.httpEquiv = 'origin-trial'; |
| 54 | meta.content = 'YOUR_THIRD_PARTY_ORIGIN_TRIAL_TOKEN'; |
| 55 | document.head.appendChild(meta); |
| 56 | })() |
| 57 | ``` |
| 58 | |
| 59 | Currently third-party Origin Trial doesn't support `Origin-Trial` HTTP |
| 60 | response header. See [this doc][third-party-ot-dd] for more details. |
| 61 | |
| 62 | ### Origin Trial and the backend feature |
| 63 | |
| 64 | The origin trial token works only when the backend of this feature is enabled. |
| 65 | Currently, the backend is gradually being rolled out. So the backend may not be |
| 66 | enabled in your Chrome yet. If you want to try this feature using an Origin |
| 67 | Trial token, please enable the backend at |
| 68 | [chrome://flags/#enable-compression-dictionary-transport-backend][backend-flag]. |
| 69 | |
| 70 | #### Why the backend is not enabled for all Chrome yet? |
| 71 | |
| 72 | When the backend is enabled, Chrome will check the dictionary database while |
| 73 | fetching resources. This may negatively affect Chrome's loading performance. |
| 74 | Therefore, we are conducting experiments to ensure that this does not cause |
| 75 | regressions before rolling it out to all users. |
| 76 | |
Alison Gale | 59c007a | 2024-04-20 03:05:40 | [diff] [blame] | 77 | TODO(crbug.com/40255884): When we enable the backend for all Chrome, remove this |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 78 | section. |
| 79 | |
| 80 | ## Feature detection |
| 81 | |
| 82 | If you want to check whether the Compression Dictionary Transport feature is |
| 83 | enabled or not, you can try the following code: |
| 84 | |
| 85 | ```javascript |
Tsuyoshi Horo | 6ca3287f | 2024-05-21 14:43:55 | [diff] [blame] | 86 | document.createElement('link').relList.supports('compression-dictionary') |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 87 | ``` |
| 88 | |
| 89 | If the code above returns true, the Compression Dictionary Transport feature is |
| 90 | enabled. |
| 91 | |
Tsuyoshi Horo | 6ca3287f | 2024-05-21 14:43:55 | [diff] [blame] | 92 | Note: Until M126, `dictionary` was used instead of `compression-dictionary`. |
| 93 | |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 94 | ## Registering dictionaries |
| 95 | |
| 96 | When Chrome receives a HTTP response with `use-as-dictionary: <options>` header, |
| 97 | and if the the response type is not opaque, Chrome registers the response as a |
| 98 | dictionary. |
| 99 | |
Tsuyoshi Horo | ceee8dbd | 2024-05-25 00:39:53 | [diff] [blame] | 100 | Chrome supports following options (see [the explainer][explainer] and [the |
| 101 | spec draft][httpbis-draft] for more details): |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 102 | |
| 103 | - **match** |
Tsuyoshi Horo | ceee8dbd | 2024-05-25 00:39:53 | [diff] [blame] | 104 | - The URL Pattern [URLPattern] to use for request matching. |
| 105 | - **match-dest** |
| 106 | - List of request destinations for the dictionary to match. |
| 107 | - **id** |
| 108 | - The dictionary ID. |
| 109 | - This ID is sent to the server in a "Dictionary-ID" request header when the |
| 110 | dictionary is available. |
Tsuyoshi Horo | 49d12a1e | 2023-08-10 21:42:03 | [diff] [blame] | 111 | - **type** |
| 112 | - Dictionary format. |
| 113 | - This field is optional and defaults to `raw`. |
| 114 | - Currently Chrome only supports `raw`. So if this field is set but it is not |
| 115 | `raw`, Chrome doesn't register the response as a dictionary. This logic of |
| 116 | checking **type** was [introduced at M118][type-option-cl]. |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 117 | |
| 118 | Note: These options fields are expected to change when we officially launch this |
| 119 | feature, depending on the outcome of [the spec discussion][httpbis-draft]. |
| 120 | |
Tsuyoshi Horo | ceee8dbd | 2024-05-25 00:39:53 | [diff] [blame] | 121 | ## Dictionary lifetime |
| 122 | |
| 123 | The lifetime of registered dictionary is calculated from the response's |
| 124 | [freshness](https://datatracker.ietf.org/doc/html/rfc9111#name-freshness). |
| 125 | |
| 126 | While running the Origin Trial experiment, the max expiration time is |
| 127 | limited to 30 days. This limitation can be removed by enabling |
| 128 | [chrome://flags/#enable-compression-dictionary-transport][flag]. |
| 129 | |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 130 | ## Fetching dedicated dictionaries |
| 131 | |
| 132 | Chrome fetches a dedicated dictionary when it detects |
Tsuyoshi Horo | 6ca3287f | 2024-05-21 14:43:55 | [diff] [blame] | 133 | `<link rel="compression-dictionary" href="DICTIONARY_URL">` in the page, or |
| 134 | `Link: <DICTIONARY_URL>; rel="compression-dictionary"` HTTP response header is |
| 135 | set in the response of the page's HTML file. |
| 136 | |
| 137 | Note: Until M126, `dictionary` was used instead of `compression-dictionary`. |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 138 | |
| 139 | ## Using dictionaries |
| 140 | |
| 141 | While fetching a HTTP request, Chrome match the request against the available |
Tsuyoshi Horo | ceee8dbd | 2024-05-25 00:39:53 | [diff] [blame] | 142 | dictionary `match` URL patterns. |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 143 | |
Tsuyoshi Horo | ceee8dbd | 2024-05-25 00:39:53 | [diff] [blame] | 144 | If a dictionary is available for the request, Chrome will add `dcb` and `dcz`in |
| 145 | the `Accept-Encoding` request header, as well as a |
| 146 | `Available-Dictionary: <SHA-256>` header with the hash of the dictionary. |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 147 | |
| 148 | ## Supported compression scheme |
| 149 | |
Tsuyoshi Horo | 27c43a3f | 2023-08-22 07:36:14 | [diff] [blame] | 150 | Chrome 117.0.5857.0 introduced support for Shared Brotli, and Chrome |
| 151 | 118.0.5952.0 adds support for Shared Zstandard. |
| 152 | |
| 153 | Shared Zstandard can be enabled/disabled from |
| 154 | [chrome://flags/#enable-shared-zstd][shared-zstd-flag]. |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 155 | |
Tsuyoshi Horo | ceee8dbd | 2024-05-25 00:39:53 | [diff] [blame] | 156 | Until M126, `br-d` and `zstd-d` encoding was used. After M127, `dcb` and `dcz` |
| 157 | encodings are used. See [this spec |
| 158 | change](https://github.com/httpwg/http-extensions/pull/2784) for more details |
| 159 | about this change of the encoding. |
| 160 | |
Tsuyoshi Horo | 47cfd6ea | 2023-11-28 11:10:35 | [diff] [blame] | 161 | ## Supported HTTP protocol |
| 162 | |
| 163 | From Chrome 121, Chrome may not use stored shared dictionares when the |
Tsuyoshi Horo | 42fb8d0 | 2024-04-11 01:47:55 | [diff] [blame] | 164 | connection is using HTTP/1 for non-localhost requests. From Chrome 125, Chrome |
| 165 | may not use stored shared dictionares when the connection is using HTTP/2 for |
| 166 | non-localhost requests. |
| 167 | Also Chrome may not use shared dictionares when the HTTPS connection's |
| 168 | certificate is not rooted by a well known root CA (eg: using a user installed |
| 169 | root certificate). This is for an investigation for an issue that some network |
| 170 | appliances are interfering with HTTPS traffic by inspecting encrypted responses |
| 171 | but failing to properly decode the shared dictionary encoded content. |
Tsuyoshi Horo | 47cfd6ea | 2023-11-28 11:10:35 | [diff] [blame] | 172 | |
| 173 | If you want to use shared dictionaries with HTTP/1, please enable |
Tsuyoshi Horo | 42fb8d0 | 2024-04-11 01:47:55 | [diff] [blame] | 174 | [chrome://flags/#enable-compression-dictionary-transport-allow-http1][allow-http1-flag]. |
| 175 | If you want to use shared dictionaries with HTTP/2, please enable |
| 176 | [chrome://flags/#enable-compression-dictionary-transport-allow-http2][allow-http2-flag]. |
Tsuyoshi Horo | 2cce8d5 | 2023-12-04 15:07:05 | [diff] [blame] | 177 | Also if you want to use shared dictionaries over the HTTPS connection which |
| 178 | certificate is not rooted by a well known root CA, please disable |
| 179 | [chrome://flags/#enable-compression-dictionary-transport-require-known-root-cert][require-known-root-ca-flag]. |
Tsuyoshi Horo | 47cfd6ea | 2023-11-28 11:10:35 | [diff] [blame] | 180 | |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 181 | ## Debugging |
| 182 | |
| 183 | ### Managing registered dictionaries |
| 184 | |
| 185 | Developers can manage the registered dictionaries in |
| 186 | [chrome://net-internals/#sharedDictionary][net-internals-sd]. |
| 187 | |
| 188 | ### DevTools |
| 189 | |
| 190 | Developers can check the related HTTP request and response headers |
Tsuyoshi Horo | ceee8dbd | 2024-05-25 00:39:53 | [diff] [blame] | 191 | (`Use-As-Dictionary`, `Available-Dictionary`, `Accept-Encoding` and |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 192 | `Content-Encoding`) using DevTools' Network tab. |
| 193 | |
| 194 | ## Known issues |
| 195 | |
| 196 | - [crbug.com/1468156](crbug.com/1468156): `encodedBodySize` property and |
| 197 | `transferSize` property of `PerformanceResourceTiming` for shared dictionary |
| 198 | compressed response are wrong. Currently it returns as if the response is not |
| 199 | compressed. |
| 200 | |
Tsuyoshi Horo | 40d4e43 | 2024-02-08 12:42:22 | [diff] [blame] | 201 | ## Changes in M123 |
Tsuyoshi Horo | 02878d3 | 2024-01-12 05:21:57 | [diff] [blame] | 202 | |
Tsuyoshi Horo | 40d4e43 | 2024-02-08 12:42:22 | [diff] [blame] | 203 | The following changes have been made to Chrome since M123 to keep up with the |
| 204 | changes in specifications. |
Tsuyoshi Horo | 02878d3 | 2024-01-12 05:21:57 | [diff] [blame] | 205 | |
Tsuyoshi Horo | 40d4e43 | 2024-02-08 12:42:22 | [diff] [blame] | 206 | - Changed Content-Encoding name "br-d" "zstd-d" |
Tsuyoshi Horo | 02878d3 | 2024-01-12 05:21:57 | [diff] [blame] | 207 | - Changed match to use URLPattern |
Tsuyoshi Horo | 02878d3 | 2024-01-12 05:21:57 | [diff] [blame] | 208 | - Added support for a server-provided dictionary id |
Tsuyoshi Horo | 47afd65 | 2024-01-24 11:47:09 | [diff] [blame] | 209 | - Stop using "expires" value of "Use-As-Dictionary" header, and use the cache |
| 210 | expiration time calculated from the response's freshness instead. |
Tsuyoshi Horo | 02878d3 | 2024-01-12 05:21:57 | [diff] [blame] | 211 | - Removed support for hash negotiation and force use of sha-256 |
Tsuyoshi Horo | 02878d3 | 2024-01-12 05:21:57 | [diff] [blame] | 212 | - Added the dictionary hash to the compressed response |
Tsuyoshi Horo | 02878d3 | 2024-01-12 05:21:57 | [diff] [blame] | 213 | - Dictionary hashes changed to sf-binary |
Tsuyoshi Horo | 1659f91 | 2024-01-24 06:30:03 | [diff] [blame] | 214 | - Use "Available-Dictionary" header instead of "Sec-Available-Dictionary" |
Tsuyoshi Horo | d343478b | 2024-02-07 01:45:08 | [diff] [blame] | 215 | - Added support for match-dest option |
Tsuyoshi Horo | 02878d3 | 2024-01-12 05:21:57 | [diff] [blame] | 216 | |
Tsuyoshi Horo | 6ca3287f | 2024-05-21 14:43:55 | [diff] [blame] | 217 | ## Changes in M127 |
| 218 | |
| 219 | The following changes have been made to Chrome since M127 to keep up with the |
| 220 | changes in specifications. |
| 221 | |
| 222 | - `compression-dictionary` rel attribute is used for HTML `link` element and |
| 223 | HTTP `Link:` header instead of `dictionary`. |
Tsuyoshi Horo | d934bf3 | 2024-05-23 02:02:45 | [diff] [blame] | 224 | - Changed Content-Encoding to use "dcb" and "dcz". |
| 225 | See [this spec change](https://github.com/httpwg/http-extensions/pull/2784). |
| 226 | |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 227 | ## Demo sites |
| 228 | |
| 229 | There are a few demo sites that you can use to test the feature: |
| 230 | |
| 231 | - Shopping site demo (dynamic resources flow) |
| 232 | <https://compression-dictionary-transport-shop-demo.glitch.me/> |
| 233 | - Three JS demo (static resources flow) |
| 234 | <https://compression-dictionary-transport-threejs-demo.glitch.me/> |
| 235 | |
| 236 | [explainer]: https://github.com/WICG/compression-dictionary-transport |
| 237 | [flag]: chrome://flags/#enable-compression-dictionary-transport |
| 238 | [backend-flag]: chrome://flags/#enable-compression-dictionary-transport-backend |
Tsuyoshi Horo | 27c43a3f | 2023-08-22 07:36:14 | [diff] [blame] | 239 | [shared-zstd-flag]: chrome://flags/#enable-shared-zstd |
Tsuyoshi Horo | ceee8dbd | 2024-05-25 00:39:53 | [diff] [blame] | 240 | [allow-http1-flag]: chrome://flags/#enable-compression-dictionary-transport-allow-http1 |
| 241 | [allow-http2-flag]: chrome://flags/#enable-compression-dictionary-transport-allow-http2 |
Tsuyoshi Horo | 2cce8d5 | 2023-12-04 15:07:05 | [diff] [blame] | 242 | [require-known-root-ca-flag]: chrome://flags/#enable-compression-dictionary-transport-require-known-root-cert |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 243 | [shared_dictionary_readme]: ../../services/network/shared_dictionary/README.md#flags |
| 244 | [ot-blog]: https://developer.chrome.com/blog/origin-trials/ |
| 245 | [ot-console]: https://developer.chrome.com/origintrials/#/trials/active |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 246 | [third-party-ot-dd]: https://docs.google.com/document/d/1xALH9W7rWmX0FpjudhDeS2TNTEOXuPn4Tlc9VmuPdHA/edit#heading=h.bvw2lcb2dczg |
Tsuyoshi Horo | ceee8dbd | 2024-05-25 00:39:53 | [diff] [blame] | 247 | [httpbis-draft]: https://datatracker.ietf.org/doc/draft-ietf-httpbis-compression-dictionary/ |
Tsuyoshi Horo | 61d47db4 | 2023-08-03 23:02:25 | [diff] [blame] | 248 | [net-internals-sd]: chrome://net-internals/#sharedDictionary |
Tsuyoshi Horo | 49d12a1e | 2023-08-10 21:42:03 | [diff] [blame] | 249 | [type-option-cl]: https://chromiumdash.appspot.com/commit/169031f4af2cbdc529f48160f1df20b4ca8b6cc1 |
Tsuyoshi Horo | ceee8dbd | 2024-05-25 00:39:53 | [diff] [blame] | 250 | [URLPattern]: https://urlpattern.spec.whatwg.org/ |