[{"data":1,"prerenderedAt":887},["ShallowReactive",2],{"content:\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fcompression-dictionary-transport":3,"surroundings:\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fcompression-dictionary-transport":879},{"id":4,"title":5,"body":6,"description":858,"extension":859,"meta":860,"navigation":872,"path":873,"seo":874,"stem":877,"__hash__":878},"content\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fcompression-dictionary-transport\u002Findex.md","Compression Dictionary Transport",{"type":7,"value":8,"toc":840},"minimark",[9,14,29,54,179,184,213,217,223,229,235,241,245,250,284,287,291,308,388,402,406,409,413,420,487,491,502,506,515,622,626,636,640,655,659,685,689,695,701,707,713,717,729,744,753,762,771,780,789,798,802,825,830,833,836],[10,11,13],"h1",{"id":12},"compression-dictionary-transport-download-only-what-changed","Compression Dictionary Transport: Download Only What Changed",[15,16,17,18,23,24,28],"p",{},"This guide is part of ",[19,20,22],"a",{"href":21},"\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002F","Compression: Brotli & Zstandard",", within ",[19,25,27],{"href":26},"\u002Fnetwork-protocol-optimization\u002F","Network & Server Response Optimization",". When you deploy a new version of a JavaScript bundle, its hashed URL changes and every returning visitor downloads the whole file again, even though most of the code is identical to the version they already have. For sites that deploy daily, this means returning users repeatedly download hundreds of kilobytes they already hold.",[15,30,31,32,36,37,40,41,45,46,49,50,53],{},"Compression dictionary transport fixes this. A response can declare itself usable as a dictionary for future requests matching a URL pattern (",[33,34,35],"code",{},"Use-As-Dictionary","). On the next request matching that pattern, the browser advertises the dictionary it has (",[33,38,39],{},"Available-Dictionary",", a hash), and the server can respond with the new file compressed ",[42,43,44],"em",{},"using the old file as a dictionary"," — Brotli (",[33,47,48],{},"dcb",") or Zstandard (",[33,51,52],{},"dcz","). Because the dictionary already contains almost everything, the compressed delta is tiny: often 80–95% smaller than normal Brotli compression of the new version.",[15,55,56],{},[57,58,64,65,64,72,64,76,64,79,64,97,64,105,64,111,64,118,64,125,64,128,64,132,64,141,64,144,64,150,64,156,64,161,64,165,64,167,64,171,64,175,64],"svg",{"viewBox":59,"width":60,"role":61,"ariaLabel":62,"style":63},"0 0 760 290","100%","img","Sequence showing a browser storing a bundle as a dictionary and later receiving a new version as a small delta.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[66,67],"rect",{"className":68,"x":70,"y":70,"width":60,"height":60,"fill":71},[69],"svg-canvas","0","#ffffff",[73,74,75],"title",{},"Delta compression with a shared dictionary",[77,78,62],"desc",{},[80,81,82],"defs",{},[83,84,91],"marker",{"id":85,"viewBox":86,"refX":87,"refY":88,"markerWidth":89,"markerHeight":89,"orient":90},"fa0fc6b705","0 0 10 10","9","5","7","auto-start-reverse",[92,93],"path",{"d":94,"fill":95,"style":96},"M0 0 L10 5 L0 10 z","currentColor","fill-opacity:0.7",[66,98],{"x":99,"y":99,"width":100,"height":101,"rx":102,"fill":103,"stroke":95,"style":104},"1","758","288","10","none","stroke-opacity:0.18",[106,107,75],"text",{"x":108,"y":109,"fill":95,"style":110},"28.0","34.0","font-size:16px;font-weight:700",[66,112],{"x":113,"y":114,"width":115,"height":109,"rx":116,"fill":95,"stroke":95,"style":117},"129.0","56.0","150.0","6","fill-opacity:0.06;stroke-opacity:0.4",[106,119,124],{"x":120,"y":121,"fill":95,"style":122,"textAnchor":123},"204.0","78.0","font-size:13px;font-weight:700","middle","Browser",[66,126],{"x":127,"y":114,"width":115,"height":109,"rx":116,"fill":95,"stroke":95,"style":117},"481.0",[106,129,131],{"x":130,"y":121,"fill":95,"style":122,"textAnchor":123},"556.0","Server",[133,134],"line",{"x1":120,"y1":135,"x2":120,"y2":136,"stroke":95,"strokeWidth":137,"strokeDashArray":138,"style":140},"90.0","268.0","1.5",[139,139],"4","stroke-opacity:0.35",[133,142],{"x1":130,"y1":135,"x2":130,"y2":136,"stroke":95,"strokeWidth":137,"strokeDashArray":143,"style":140},[139,139],[133,145],{"x1":120,"y1":146,"x2":147,"y2":146,"stroke":95,"strokeWidth":137,"style":148,"markerEnd":149},"124.0","554.0","stroke-opacity:0.6","url(#fa0fc6b705)",[106,151,155],{"x":152,"y":153,"fill":95,"style":154,"textAnchor":123},"380.0","117.0","font-size:12px","GET \u002Fjs\u002Fapp.v1.js",[133,157],{"x1":130,"y1":158,"x2":159,"y2":158,"stroke":95,"strokeWidth":137,"strokeDashArray":160,"style":148,"markerEnd":149},"164.0","206.0",[88,139],[106,162,164],{"x":152,"y":163,"fill":95,"style":154,"textAnchor":123},"157.0","app.v1 + Use-As-Dictionary",[133,166],{"x1":120,"y1":120,"x2":147,"y2":120,"stroke":95,"strokeWidth":137,"style":148,"markerEnd":149},[106,168,170],{"x":152,"y":169,"fill":95,"style":154,"textAnchor":123},"197.0","GET \u002Fjs\u002Fapp.v2.js + Available-Dictionary",[133,172],{"x1":130,"y1":173,"x2":159,"y2":173,"stroke":95,"strokeWidth":137,"strokeDashArray":174,"style":148,"markerEnd":149},"244.0",[88,139],[106,176,178],{"x":152,"y":177,"fill":95,"style":154,"textAnchor":123},"237.0","dcb delta (small)",[180,181,183],"h2",{"id":182},"rapid-diagnosis","Rapid Diagnosis",[185,186,187,195,201,207],"ul",{},[188,189,190,194],"li",{},[191,192,193],"strong",{},"Check how often you deploy"," and how much of each bundle changes per release.",[188,196,197,200],{},[191,198,199],{},"Measure returning-visitor JS downloads"," in RUM (transfer size for scripts on repeat visits after deploys).",[188,202,203,206],{},[191,204,205],{},"Check browser support"," in your audience (Chromium-based browsers currently).",[188,208,209,212],{},[191,210,211],{},"Check server or CDN support"," for dictionary-compressed responses.",[180,214,216],{"id":215},"root-cause-analysis","Root Cause Analysis",[15,218,219,222],{},[191,220,221],{},"1. Hashed filenames defeat caching on change."," Any change produces a new URL and full download.",[15,224,225,228],{},[191,226,227],{},"2. Frequent deploys."," Each deploy re-downloads large unchanged portions.",[15,230,231,234],{},[191,232,233],{},"3. Large bundles."," The larger the bundle, the more delta compression saves.",[15,236,237,240],{},[191,238,239],{},"4. Shared structure across pages."," HTML pages share most of their markup; a dictionary of common HTML can shrink every page.",[180,242,244],{"id":243},"step-by-step-resolution","Step-by-Step Resolution",[246,247,249],"h3",{"id":248},"_1-mark-bundles-as-dictionaries","1. Mark bundles as dictionaries",[251,252,257],"pre",{"className":253,"code":254,"language":255,"meta":256,"style":256},"language-http shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","HTTP\u002F1.1 200 OK\nContent-Type: text\u002Fjavascript\nCache-Control: public, max-age=31536000, immutable\nUse-As-Dictionary: match=\"\u002Fjs\u002Fapp.*.js\"\n","http","",[33,258,259,266,272,278],{"__ignoreMap":256},[260,261,263],"span",{"class":133,"line":262},1,[260,264,265],{},"HTTP\u002F1.1 200 OK\n",[260,267,269],{"class":133,"line":268},2,[260,270,271],{},"Content-Type: text\u002Fjavascript\n",[260,273,275],{"class":133,"line":274},3,[260,276,277],{},"Cache-Control: public, max-age=31536000, immutable\n",[260,279,281],{"class":133,"line":280},4,[260,282,283],{},"Use-As-Dictionary: match=\"\u002Fjs\u002Fapp.*.js\"\n",[15,285,286],{},"The browser stores the response as a dictionary for future requests whose URL matches the pattern.",[246,288,290],{"id":289},"_2-serve-deltas-when-the-browser-has-a-dictionary","2. Serve deltas when the browser has a dictionary",[15,292,293,294,297,298,301,302,304,305,307],{},"When a request includes ",[33,295,296],{},"Available-Dictionary: :\u003Csha-256 base64>:"," and ",[33,299,300],{},"Accept-Encoding"," includes ",[33,303,48],{}," or ",[33,306,52],{},", look up the previous version by hash, and serve a precomputed delta.",[251,309,313],{"className":310,"code":311,"language":312,"meta":256,"style":256},"language-bash shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","# Build step: precompute a Brotli delta from the previous release.\nbrotli -q 11 --dictionary=releases\u002Fapp.v1.js -o dist\u002Fjs\u002Fapp.v2.js.dcb-from-v1 dist\u002Fjs\u002Fapp.v2.js\n# Hash of the dictionary (what the browser sends in Available-Dictionary).\nopenssl dgst -sha256 -binary releases\u002Fapp.v1.js | base64\n# trade-off: keeping deltas for several previous versions improves hit rates but\n# multiplies build artefacts; most sites keep the last 2-5 releases.\n","bash",[33,314,315,321,347,352,376,382],{"__ignoreMap":256},[260,316,317],{"class":133,"line":262},[260,318,320],{"class":319},"sjfSM","# Build step: precompute a Brotli delta from the previous release.\n",[260,322,323,327,331,334,337,340,344],{"class":133,"line":268},[260,324,326],{"class":325},"sQw3B","brotli",[260,328,330],{"class":329},"sPXB4"," -q",[260,332,333],{"class":329}," 11",[260,335,336],{"class":329}," --dictionary=releases\u002Fapp.v1.js",[260,338,339],{"class":329}," -o",[260,341,343],{"class":342},"sZ8jY"," dist\u002Fjs\u002Fapp.v2.js.dcb-from-v1",[260,345,346],{"class":342}," dist\u002Fjs\u002Fapp.v2.js\n",[260,348,349],{"class":133,"line":274},[260,350,351],{"class":319},"# Hash of the dictionary (what the browser sends in Available-Dictionary).\n",[260,353,354,357,360,363,366,369,373],{"class":133,"line":280},[260,355,356],{"class":325},"openssl",[260,358,359],{"class":342}," dgst",[260,361,362],{"class":329}," -sha256",[260,364,365],{"class":329}," -binary",[260,367,368],{"class":342}," releases\u002Fapp.v1.js",[260,370,372],{"class":371},"sPARh"," |",[260,374,375],{"class":325}," base64\n",[260,377,379],{"class":133,"line":378},5,[260,380,381],{"class":319},"# trade-off: keeping deltas for several previous versions improves hit rates but\n",[260,383,385],{"class":133,"line":384},6,[260,386,387],{"class":319},"# multiplies build artefacts; most sites keep the last 2-5 releases.\n",[15,389,390,391,394,395,397,398,401],{},"Responses must include ",[33,392,393],{},"Content-Encoding: dcb"," (or ",[33,396,52],{},") and ",[33,399,400],{},"Vary: Accept-Encoding, Available-Dictionary",".",[246,403,405],{"id":404},"_3-fall-back-cleanly","3. Fall back cleanly",[15,407,408],{},"If the dictionary hash is unknown, serve normal Brotli or gzip. The browser handles both.",[246,410,412],{"id":411},"_4-consider-custom-dictionaries-for-html","4. Consider custom dictionaries for HTML",[15,414,415,416,419],{},"A separate dictionary resource (declared via ",[33,417,418],{},"\u003Clink rel=\"compression-dictionary\" href=\"\u002Fdict\u002Fhtml.dict\">",") built from common markup can shrink every HTML page, including first navigations to new pages after the dictionary has been fetched.",[15,421,422],{},[57,423,64,426,64,429,64,432,64,434,64,437,64,439,64,446,64,453,64,458,64,462,64,468,64,472,64,476,64,483,64],{"viewBox":424,"width":60,"role":61,"ariaLabel":425,"style":63},"0 0 760 163","Bar chart comparing the transfer size of an updated JavaScript bundle with gzip, Brotli and Brotli delta compression.",[66,427],{"className":428,"x":70,"y":70,"width":60,"height":60,"fill":71},[69],[73,430,431],{},"Returning-visitor download of an updated 640KB bundle",[77,433,425],{},[66,435],{"x":99,"y":99,"width":100,"height":436,"rx":102,"fill":103,"stroke":95,"style":104},"161",[106,438,431],{"x":108,"y":109,"fill":95,"style":110},[106,440,445],{"x":441,"y":442,"fill":95,"style":443,"textAnchor":444},"219.3","70.0","font-size:13px","end","gzip",[66,447],{"x":448,"y":114,"width":449,"height":450,"rx":451,"fill":103,"stroke":95,"style":452},"231.3","436.7","19","3","fill-opacity:0.7;stroke-opacity:0.35",[106,454,457],{"x":455,"y":442,"fill":95,"style":456},"674.0","font-size:12px;font-weight:600","182KB",[106,459,461],{"x":441,"y":460,"fill":95,"style":443,"textAnchor":444},"101.0","Brotli 11",[66,463],{"x":448,"y":464,"width":465,"height":450,"rx":451,"fill":466,"stroke":466,"style":467},"87.0","369.5","#0466c8","fill-opacity:0.55;stroke-opacity:0.9",[106,469,471],{"x":470,"y":460,"fill":95,"style":456},"606.8","154KB",[106,473,475],{"x":441,"y":474,"fill":95,"style":443,"textAnchor":444},"132.0","Brotli delta from previous version",[66,477],{"x":448,"y":478,"width":479,"height":450,"rx":451,"fill":480,"stroke":481,"style":482},"118.0","26.4","#ffc300","#b8860b","fill-opacity:0.7;stroke-opacity:0.9",[106,484,486],{"x":485,"y":474,"fill":95,"style":456},"263.7","11KB",[180,488,490],{"id":489},"verification","Verification",[15,492,493,494,304,496,498,499,501],{},"In Chrome DevTools, the Network panel shows ",[33,495,393],{},[33,497,52],{}," for delta-compressed responses, and the transfer size is far smaller than the resource size. The ",[33,500,39],{}," request header appears on matching requests. In RUM, compare script transfer sizes for returning visitors after a deploy with the pre-dictionary baseline.",[180,503,505],{"id":504},"worked-example-a-web-app-with-daily-deploys","Worked Example: A Web App With Daily Deploys",[15,507,508,509,511,512,514],{},"A collaborative editing app shipped a 1.1MB (uncompressed) main bundle and deployed every weekday. Returning users downloaded about 290KB of Brotli-compressed JavaScript after each deploy. The team added ",[33,510,35],{}," to the bundle and generated Brotli deltas from the previous three releases at build time, served by an edge function that matched ",[33,513,39],{}," hashes. For Chromium users (78% of traffic), post-deploy bundle downloads fell to 14–40KB depending on the size of the release. Time to interactive for returning users on the first visit after a deploy improved by about 600ms on mid-range Android devices.",[15,516,517],{},[57,518,64,521,64,524,64,527,64,529,64,536,64,539,64,541,64,545,64,549,64,553,64,557,64,560,64,564,64,567,64,570,64,573,64,576,64,580,64,584,64,587,64,590,64,594,64,597,64,601,64,604,64,610,64,614,64,618,64],{"viewBox":519,"width":60,"role":61,"ariaLabel":520,"style":63},"0 0 760 165","Steps to roll out compression dictionary transport for versioned bundles.",[66,522],{"className":523,"x":70,"y":70,"width":60,"height":60,"fill":71},[69],[73,525,526],{},"Deploying delta compression",[77,528,520],{},[80,530,531],{},[83,532,534],{"id":533,"viewBox":86,"refX":87,"refY":88,"markerWidth":89,"markerHeight":89,"orient":90},"fa307d9929",[92,535],{"d":94,"fill":95,"style":96},[66,537],{"x":99,"y":99,"width":100,"height":538,"rx":102,"fill":103,"stroke":95,"style":104},"163",[106,540,526],{"x":108,"y":109,"fill":95,"style":110},[66,542],{"x":108,"y":114,"width":543,"height":464,"rx":116,"fill":466,"stroke":466,"style":544},"108.8","fill-opacity:0.14;stroke-opacity:0.9",[106,546,548],{"x":547,"y":121,"fill":95,"style":122,"textAnchor":123},"82.4","Mark",[106,550,552],{"x":547,"y":551,"fill":95,"style":154,"textAnchor":123},"96.0","Use-As-Dictionar",[106,554,556],{"x":547,"y":555,"fill":95,"style":154,"textAnchor":123},"112.0","y",[66,558],{"x":559,"y":114,"width":543,"height":464,"rx":116,"fill":466,"stroke":466,"style":544},"176.8",[106,561,563],{"x":562,"y":121,"fill":95,"style":122,"textAnchor":123},"231.2","Keep releases",[106,565,566],{"x":562,"y":551,"fill":95,"style":154,"textAnchor":123},"last 2-5 versions",[66,568],{"x":569,"y":114,"width":543,"height":464,"rx":116,"fill":466,"stroke":466,"style":544},"325.6",[106,571,572],{"x":152,"y":121,"fill":95,"style":122,"textAnchor":123},"Build deltas",[106,574,575],{"x":152,"y":551,"fill":95,"style":154,"textAnchor":123},"dcb \u002F dcz per pair",[66,577],{"x":578,"y":114,"width":543,"height":464,"rx":116,"fill":480,"stroke":481,"style":579},"474.4","fill-opacity:0.24;stroke-opacity:0.9",[106,581,583],{"x":582,"y":121,"fill":95,"style":122,"textAnchor":123},"528.8","Serve",[106,585,586],{"x":582,"y":551,"fill":95,"style":154,"textAnchor":123},"match",[106,588,589],{"x":582,"y":555,"fill":95,"style":154,"textAnchor":123},"Available-Dictiona",[106,591,593],{"x":582,"y":592,"fill":95,"style":154,"textAnchor":123},"128.0","ry",[66,595],{"x":596,"y":114,"width":543,"height":464,"rx":116,"fill":466,"stroke":466,"style":544},"623.2",[106,598,600],{"x":599,"y":121,"fill":95,"style":122,"textAnchor":123},"677.6","Fallback",[106,602,603],{"x":599,"y":551,"fill":95,"style":154,"textAnchor":123},"plain br or gzip",[133,605],{"x1":606,"y1":607,"x2":608,"y2":607,"stroke":95,"strokeWidth":137,"style":148,"markerEnd":609},"136.8","99.5","174.8","url(#fa307d9929)",[133,611],{"x1":612,"y1":607,"x2":613,"y2":607,"stroke":95,"strokeWidth":137,"style":148,"markerEnd":609},"285.6","323.6",[133,615],{"x1":616,"y1":607,"x2":617,"y2":607,"stroke":95,"strokeWidth":137,"style":148,"markerEnd":609},"434.4","472.4",[133,619],{"x1":620,"y1":607,"x2":621,"y2":607,"stroke":95,"strokeWidth":137,"style":148,"markerEnd":609},"583.2","621.2",[180,623,625],{"id":624},"choosing-dictionaries-and-match-patterns","Choosing Dictionaries and Match Patterns",[15,627,628,629,631,632,635],{},"The ",[33,630,586],{}," pattern decides which future requests can use a dictionary. For versioned bundles, a pattern like ",[33,633,634],{},"\u002Fjs\u002Fapp.*.js"," matches every future version of the same bundle. Keep patterns specific to avoid using an unrelated file as a dictionary (which only wastes the opportunity; correctness is preserved by the hash check). For many small chunks, delta compression helps less per file; consider fewer, larger stable chunks for the code that changes rarely. Dictionaries are stored per origin and are partitioned like caches, and browsers may evict them; always keep normal compression as the fallback.",[180,637,639],{"id":638},"measuring-the-benefit","Measuring the Benefit",[15,641,642,643,304,645,647,648,651,652,654],{},"The benefit appears only for returning visitors after a deploy, so measure that cohort specifically. In RUM, record the transferred size of the main bundle along with whether the response used ",[33,644,48],{},[33,646,52],{}," (visible via ",[33,649,650],{},"encodedBodySize"," being much smaller than usual) and the time since the last deploy. Compare first-visit-after-deploy sessions before and after enabling dictionaries. Server-side, log the share of requests that arrive with an ",[33,653,39],{}," header and the share you could serve a delta for; a low match rate usually means too few previous versions are kept or the match pattern is too narrow.",[180,656,658],{"id":657},"common-mistakes","Common Mistakes",[185,660,661,667,673,679],{},[188,662,663,666],{},[191,664,665],{},"Missing Vary on Available-Dictionary."," Caches could serve a delta to a client without the dictionary.",[188,668,669,672],{},[191,670,671],{},"Unsafe deltas from cross-origin dictionaries."," Dictionaries must be same-origin (or CORS-readable) to prevent data leaks.",[188,674,675,678],{},[191,676,677],{},"No fallback."," Clients without the dictionary must receive normal compression.",[188,680,681,684],{},[191,682,683],{},"Keeping too few old versions."," Users who skip several releases fall back to full downloads.",[180,686,688],{"id":687},"edge-cases","Edge Cases",[15,690,691,694],{},[191,692,693],{},"CDN caching of deltas."," The cache key must include the dictionary hash; some CDNs support this natively, others need edge logic.",[15,696,697,700],{},[191,698,699],{},"Privacy."," Dictionaries are partitioned and cleared with site data, like cookies and caches.",[15,702,703,706],{},[191,704,705],{},"Service workers."," Requests from service workers can also use dictionaries, but test the full flow.",[15,708,709,712],{},[191,710,711],{},"Very small changes."," Even a one-line change produces a new hash; deltas handle it efficiently.",[180,714,716],{"id":715},"faq","FAQ",[718,719,722,726],"details",{"className":720},[721],"faq-item",[723,724,725],"summary",{},"Which browsers support compression dictionary transport?",[15,727,728],{},"Chromium-based browsers currently support it. Other browsers ignore the headers and receive normal compression.",[718,730,732,735],{"className":731},[721],[723,733,734],{},"What are dcb and dcz?",[15,736,737,738,740,741,743],{},"Content encodings for dictionary-compressed Brotli (",[33,739,48],{},") and dictionary-compressed Zstandard (",[33,742,52],{},").",[718,745,747,750],{"className":746},[721],[723,748,749],{},"Is this the same as SDCH?",[15,751,752],{},"It is a successor in spirit. SDCH was an older Chrome experiment that was removed; the new standard addresses its security and privacy issues.",[718,754,756,759],{"className":755},[721],[723,757,758],{},"Does it help first-time visitors?",[15,760,761],{},"Not for delta updates, since they have no previous version. Custom dictionaries for HTML can help subsequent pages within a first visit.",[718,763,765,768],{"className":764},[721],[723,766,767],{},"How do I generate deltas?",[15,769,770],{},"Use Brotli or zstd command-line tools or libraries with the previous version as a dictionary, at build time for static assets.",[718,772,774,777],{"className":773},[721],[723,775,776],{},"Can CDNs do this automatically?",[15,778,779],{},"Some CDNs have begun offering dictionary compression features. Check your provider; otherwise, edge functions can implement it.",[718,781,783,786],{"className":782},[721],[723,784,785],{},"Is it secure?",[15,787,788],{},"The standard restricts dictionaries to same-origin or CORS-readable resources and uses hashes to ensure the right dictionary is used, addressing the issues of earlier approaches.",[718,790,792,795],{"className":791},[721],[723,793,794],{},"Do dictionaries use extra storage on the device?",[15,796,797],{},"Yes, the dictionary is stored like a cached response. Browsers manage this storage and evict dictionaries like other cache entries.",[180,799,801],{"id":800},"related","Related",[185,803,804,811,818],{},[188,805,806,810],{},[19,807,809],{"href":808},"\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fprecompressing-static-assets-at-build-time\u002F","Precompressing static assets at build time"," — the baseline for static files.",[188,812,813,817],{},[19,814,816],{"href":815},"\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fzstandard-content-encoding-for-the-web\u002F","Zstandard Content-Encoding for the web"," — dcz builds on zstd.",[188,819,820,824],{},[19,821,823],{"href":822},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcache-invalidation-patterns\u002Finvalidating-service-worker-caches-on-deploy\u002F","Invalidating service worker caches on deploy"," — the other repeat-visit cost of deploys.",[826,827,829],"script",{"type":828},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"Compression Dictionary Transport: Download Only What Changed\",\n  \"description\": \"How compression dictionary transport works, how to deploy delta compression for versioned bundles, and when custom dictionaries help HTML and API responses.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Mark bundles as dictionaries\",\n      \"text\": \"The browser stores the response as a dictionary for future requests whose URL matches the pattern.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Serve deltas when the browser has a dictionary\",\n      \"text\": \"When a request includes Available-Dictionary: :: and Accept-Encoding includes dcb or dcz, look up the previous version by hash, and serve a precomputed delta.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Fall back cleanly\",\n      \"text\": \"If the dictionary hash is unknown, serve normal Brotli or gzip.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Consider custom dictionaries for HTML\",\n      \"text\": \"A separate dictionary resource (declared via ) built from common markup can shrink every HTML page, including first navigations to new pages after the dictionary has been fetched.\"\n    }\n  ]\n}\n",[826,831,832],{"type":828},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"Compression Dictionary Transport: Download Only What Changed\",\n  \"description\": \"How compression dictionary transport works, how to deploy delta compression for versioned bundles, and when custom dictionaries help HTML and API responses.\",\n  \"datePublished\": \"2026-10-06\",\n  \"dateModified\": \"2026-10-06\",\n  \"author\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"mainEntityOfPage\": {\n    \"@type\": \"WebPage\",\n    \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fcompression-dictionary-transport\u002F\"\n  }\n}\n",[826,834,835],{"type":828},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 1,\n      \"name\": \"Home\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 2,\n      \"name\": \"Network & Server Response Optimization\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"Compression: Brotli & Zstandard\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Compression Dictionary Transport\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fcompression-dictionary-transport\u002F\"\n    }\n  ]\n}\n",[837,838,839],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}html pre.shiki code .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}",{"title":256,"searchDepth":268,"depth":268,"links":841},[842,843,844,850,851,852,853,854,855,856,857],{"id":182,"depth":268,"text":183},{"id":215,"depth":268,"text":216},{"id":243,"depth":268,"text":244,"children":845},[846,847,848,849],{"id":248,"depth":274,"text":249},{"id":289,"depth":274,"text":290},{"id":404,"depth":274,"text":405},{"id":411,"depth":274,"text":412},{"id":489,"depth":268,"text":490},{"id":504,"depth":268,"text":505},{"id":624,"depth":268,"text":625},{"id":638,"depth":268,"text":639},{"id":657,"depth":268,"text":658},{"id":687,"depth":268,"text":688},{"id":715,"depth":268,"text":716},{"id":800,"depth":268,"text":801},"How compression dictionary transport works, how to deploy delta compression for versioned bundles, and when custom dictionaries help HTML and API responses.","md",{"slug":861,"type":862,"breadcrumb":863,"datePublished":871,"dateModified":871},"compression-dictionary-transport","article",[864,867,868,869],{"name":865,"url":866},"Home","\u002F",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":870},"\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fcompression-dictionary-transport\u002F","2026-10-06",true,"\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fcompression-dictionary-transport",{"title":875,"description":876},"Compression Dictionary Transport for Smaller Updates","Shared dictionaries let browsers download only what changed in updated bundles: Use-As-Dictionary, Available-Dictionary, dcb and dcz encodings, setup and pitfalls.","network-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fcompression-dictionary-transport\u002Findex","KfkepEVO6B-wA_2PWbUzgJYiBx2LBtiZOOWmsKy9pL4",[880,883],{"title":22,"path":881,"stem":882,"children":-1},"\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard","network-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Findex",{"title":884,"path":885,"stem":886,"children":-1},"Enabling Brotli on nginx and CDNs","\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fenabling-brotli-on-nginx-and-cdns","network-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fenabling-brotli-on-nginx-and-cdns\u002Findex",1791308069638]