Verbeter de compressie-efficiëntie met gedeelde woordenboeken

Gepubliceerd: 6 maart 2024

Datacompressie is een beproefde techniek voor prestatie-optimalisatie die de grootte van geschikte paginabronnen verkleint. Het was enige tijd gebruikelijk om gzip voornamelijk op webservers te gebruiken om veelgebruikte tekstgebaseerde paginabronnen, zoals HTML-, CSS- en JavaScript-bestanden, te comprimeren en naar de client te sturen waar ze konden worden gedecomprimeerd. Het resultaat is snellere laadtijden voor bronnen zonder het beoogde gedrag van een pagina te beïnvloeden.

Hoewel gzip op zichzelf al zeer effectief is, zijn er de afgelopen jaren verdere verbeteringen in webcompressie gerealiseerd. In 2016 werd het Brotli-algoritme in Chrome geïntroduceerd, wat over het algemeen betere compressieverhoudingen opleverde voor geschikte bronnen. Eind 2017 ondersteunden alle moderne browsers Brotli en begon serverondersteuning hiervoor wijdverspreid te worden. Recenter heeft Chrome ZStandard-compressie geïntroduceerd .

Maar het werk stopt daar niet! Het Chrome-team heeft gewerkt aan het online beschikbaar maken van gedeelde woordenboeken. Deze zijn nu beschikbaar in een proefversie voor zowel Brotli als ZStandard . Gedeelde woordenboeken kunnen de compressie van Brotli en ZStandard aanvullen om aanzienlijk hogere compressieverhoudingen te leveren voor websites die regelmatig bijgewerkte code leveren, en kunnen in sommige gevallen zelfs compressieverhoudingen van 90% of beter leveren. Dit bericht gaat dieper in op hoe gedeelde woordenboeken werken en hoe u zich kunt registreren voor de proefversies om ze voor Brotli en ZStandard op uw website te gebruiken. U kunt ook deze video bekijken:

Gedeelde woordenboeken uitgelegd

Compressie is een proces waarbij redundante sequenties in een invoer worden gevonden en die informatie wordt gebruikt om een ​​veel kleinere uitvoer te creëren, die later kan worden teruggedraaid. Compressie werkt goed op het web omdat het de laadtijd van bronnen aanzienlijk verkort. Zowel Brotli als ZStandard kunnen hun effectiviteit verder vergroten door gebruik te maken van een compressiewoordenboek , een verzameling extra patronen die deze algoritmen tijdens de compressie kunnen gebruiken. Sterker nog, de hoge efficiëntie van Brotli wordt tot op zekere hoogte bereikt door gebruik te maken van een intern woordenboek.

Aangepaste , door de gebruiker samengestelde woordenboeken kunnen echter worden gebruikt met Brotli en ZStandard, die patronen bevatten die specifiek zijn voor bepaalde bronnen. In de praktijk is een aangepast woordenboek een extern bestand dat op elke invoer kan worden toegepast. Woordenboeken kunnen zeer specifiek zijn voor de productiecode van een applicatie, of eigenlijk voor alle content. De toepasbaarheid van een bepaald woordenboek op de invoer kan een grote impact hebben op de algehele compressie-efficiëntie. Woordenboeken die sterk lijken op de inhoud van een invoer, leveren uitvoer op met hogere compressieverhoudingen dan woordenboeken met generieke of ongelijksoortige inhoud.

Hier is een voorbeeld van hoe effectief een aangepast compressiewoordenboek kan zijn: stel dat uw website het Angular-framework gebruikt en de huidige versie die u gebruikt versie 1.7.9 is. Deze versie van het Angular-framework is ongecomprimeerd ongeveer 172 KiB groot. Wanneer gecomprimeerd met de standaardinstellingen van Brotli, wordt de bestandsgrootte ongeveer 53 KiB. Dit levert een compressieverhouding van bijna 70% op. Stel echter dat u later besluit te upgraden naar Angular 1.8.3. Aangezien deze versie van Angular ongeveer even groot is als versie 1.7.9, kunt u vrijwel dezelfde compressieverhouding verwachten als de vorige versie.

Dit is waar een aangepast woordenboek van pas kan komen door gebruik te maken van een proces dat deltacompressie wordt genoemd. Dit houdt in dat een woordenboek van een eerdere versie van een resource kan worden gebruikt om een ​​latere versie te comprimeren. Uitgaande van het vorige voorbeeld: als u versie 1.8.3 van Angular comprimeerde met versie 1.7.9 als woordenboek, zou de uitvoer iets meer dan 4 KB zijn. Dit komt neer op een compressieverhouding van bijna 98% . Het is duidelijk dat compressiewoordenboeken een grote impact kunnen hebben op de laadprestaties, en hun effectiviteit is al bewezen in praktijktoepassingen !

Er is echter een uitdaging om deze flow op het web te laten werken. Het probleem is dat als je een woordenboek gebruikt om een ​​bron te comprimeren, je datzelfde woordenboek nodig hebt om deze te decomprimeren . Deze flow is al eerder op het web geprobeerd – namelijk SDCH – maar was lastig veilig te implementeren. Dit nieuwste voorstel voor gedeelde woordenboekcompressie pakt deze problemen aan en biedt tegelijkertijd aanzienlijke voordelen voor zowel statische als dynamische bronnen.

Hoe Chrome reclame maakt voor ondersteuning van gedeelde woordenboeken

Alle browsers maken de compressiealgoritmen die ze ondersteunen bekend via de Accept-Encoding aanvraagheader . De inhoud van de header is een door komma's gescheiden lijst met ondersteunde coderingen:

Accept-Encoding: gzip, br, zstd

Deze specifieke Accept-Encoding header geeft aan dat de browser die de resource aanvraagt ​​de compressiealgoritmen gzip, Brotli en ZStandard ondersteunt. Een webserver die op de aanvraag reageert, kan vervolgens bepalen welk algoritme moet worden gebruikt om de aanvraag te beantwoorden.

Wanneer ondersteuning voor gedeelde woordenboeken is ingeschakeld en er een relevant woordenboek beschikbaar is voor een resource, worden er extra tokens toegevoegd aan de Accept-Encoding header. Deze tokens zijn br-d voor Brotli en zstd-d voor Zstandard. Chrome neemt ook de hash van een beschikbaar woordenboek op, wat hieronder wordt besproken.

Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:

Als een webserver is geconfigureerd om dit token te herkennen en het woordenboek herkent, kan deze op dat verzoek reageren met een resource die is gecomprimeerd met het woordenboek voor de betreffende codering. Hoe dit in de praktijk wordt bereikt, hangt af van of het verzoek een statische of dynamische resource betreft.

Gedeelde woordenboekcompressie voor statische bronnen

Een statische paginabron is een bron die altijd dezelfde respons genereert voor een opgevraagde URL. Veelvoorkomende voorbeelden van comprimeerbare statische paginabronnen zijn JavaScript- en CSS-bestanden. Deze bronnen worden doorgaans op de een of andere manier geversieerd voor cachedoeleinden, soms met een hash van de bestandsinhoud in de bestandsnaam (bijvoorbeeld styles.abcd1234.css ), of een andere methode om de bron te scannen. Deze brontypen zijn een goede kandidaat voor de deltacompressie die gedeelde woordenboeken bieden, omdat statische bronnen vaak langdurig in de cache worden opgeslagen en met enige frequentie worden bijgewerkt.

Een woordenboek kan worden opgegeven voor een statische resource door de Use-As-Dictionary responsheader ervoor in te stellen. De header accepteert een van de weinige sleutel/waarde-paren, maar de enige vereiste is match , die URLPattern syntaxis accepteert en het resourcepad specificeert waar het woordenboek moet worden gebruikt:

Use-As-Dictionary: match="/dist/styles.*.css"

Beschouw de Use-As-Dictionary header als een mechanisme dat van toepassing is op toekomstige versies van een resource die voldoen aan het daarin gespecificeerde patroon. Stel dat uw website al zijn stijlen in één CSS-bestand verzendt. Stel dat de eerste versie van die resource zich in /dist/styles.v1.css bevindt en wordt verzonden met een Use-As-Dictionary responsheader met de match /dist/styles.*.css .

Na enige tijd werkt u de CSS van uw website bij en verzendt u een nieuwe versie ervan naar /dist/styles.v2.css . Omdat de match in de Use-As-Dictionary responsheader van de vorige versie op deze aanvraag van toepassing is, stuurt de browser een Available-Dictionary header met een hash van het woordenboek, gecodeerd als een gestructureerde veldbytereeks :

Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:

Op dit punt is het aan de server om compressie aan zijn kant te configureren om ervoor te zorgen dat het bijbehorende woordenboek wordt gebruikt. De met dat woordenboek gecomprimeerde bron wordt vervolgens verzonden en het beschikbare woordenboek in de browsercache van de gebruiker wordt gebruikt om het te decomprimeren.

Als u regelmatig nieuwe code voor uw website verzendt, kan deltacompressie een groot verschil maken. Het proces is echter flexibel. Als de browser niet vaststelt dat er een woordenboek beschikbaar is in de cache van de gebruiker, worden de extra br-d of zstd-d tokens niet gespecificeerd in de Accept-Encoding header. In dat geval is de standaardcompressiemethode van toepassing.

Gedeelde woordenboekcompressie voor dynamische bronnen

Dynamische bronnen kunnen ook profiteren van gedeelde woordenboekcompressie. Dynamische bronnen zijn bronnen die veranderen op basis van de context, zoals een nieuwswebsite waar de hoofdpagina regelmatig wordt bijgewerkt wanneer het nieuws bekend wordt. HTML-documenten zijn vaak dynamische bronnen. In dergelijke gevallen kan het woordenboek het grootste deel van de algemene HTML-structuur en sjablooncode van de site bevatten, wat leidt tot gecomprimeerde pagina's waar alleen de unieke delen van elke pagina worden verzonden.

Vanwege de aard van dynamisch gegenereerde bronnen moet een woordenboek op de client worden geladen voor later gebruik. Het vooraf laden van een woordenboek betekent dat het toepassen van gedeelde woordenboekcompressie op dynamische bronnen speculatief is. De hoop is in dergelijke gevallen dat uw website voldoende verkeer ontvangt om de kosten van het woordenboek over een groot aantal navigaties te kunnen terugverdienen. Mocht u besluiten dit te proberen, dan is de eerste stap het specificeren van de locatie van het woordenboek via een <link> -element in de HTML van uw pagina:

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

Wanneer Chrome dit <link> -element tegenkomt, kan het woordenboek worden opgehaald zodra de pagina inactief is en een lage prioriteit heeft om bandbreedteconflicten te voorkomen. De respons voor het woordenboek zelf moet een Use-As-Dictionary header specificeren en aangeven op welk dynamisch bronpad het van toepassing is:

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

Vanaf hier is de stroom grotendeels hetzelfde als voor statische bronnen. De browser ziet dat het woordenboek zelf van toepassing is op overeenkomende bronnen en voegt een Available-Dictionary header toe aan de aanvraag met een hash van de inhoud van het woordenboek, wederom vergelijkbaar met de eerder uitgelegde stroom voor statische bronnen.

Comprimeer statische bronnen tijdens het bouwen

Als je bekend bent met bundlers, ben je wellicht ook bekend met verschillende plugins die resources tijdens de build kunnen comprimeren en vervolgens kunnen aanbieden. Apache stelt je bijvoorbeeld in staat om directives te gebruiken om die vooraf gecomprimeerde resources op het moment van de aanvraag aan te bieden .

De meeste op Node.js gebaseerde bundlers die compressie ondersteunen, gebruiken de ingebouwde Zlib-bibliotheek van Node. Zlib biedt ondersteuning voor Brotli en bundlers die dit gebruiken, bieden doorgaans een interface om opties rechtstreeks door te geven aan Zlib, dat woordenboekondersteunde compressie ondersteunt . Hier zijn enkele bundlers die het gebruik van woordenboeken ondersteunen:

Houd er rekening mee dat beschikbare woordenboeken voor een bepaalde versie van een resource mogelijk een eerdere versie van een resource gebruiken. Dit betekent dat u het gebruikersverkeer moet analyseren en uw planning hierop moet afstemmen. Streef naar een evenwicht en genereer resources die zoveel mogelijk terugkerende gebruikers optimaal ondersteunen. CDN-providers experimenteren momenteel met gedeelde woordenboekcompressie. Er zijn nog geen implementaties beschikbaar voor openbaar gebruik, maar we verwachten dat daar verandering in komt!

Probeer het eens!

Het integreren van gedeelde woordenboekcompressie met de bestaande compressiemogelijkheden van de browser kan de laadprestaties aanzienlijk verbeteren voor websites die regelmatig bijgewerkte productiecode leveren en veel terugkerende bezoekers ontvangen. Als u gedeelde woordenboekcompressie wilt proberen, heeft u twee opties:

  1. Als u zelf met gedeelde woordenboekcompressie wilt experimenteren om een ​​idee te krijgen van hoe het werkt, kunt u de experimentele functie Compressiewoordenboektransport inschakelen op de pagina chrome://flags .
  2. Als u dit op uw productiewebsite wilt uitproberen en wilt zien hoe gedeelde woordenboekcompressie echte gebruikers ten goede kan komen, registreer u dan voor de origin trial om een ​​token te ontvangen en lees meer over hoe origin trials werken .

Conclusie

We zijn erg enthousiast over deze belangrijke vooruitgang in compressietechnologie op het web en over hoe veel sneller het bestaande applicaties die mensen dagelijks gebruiken, zou kunnen maken. We moedigen je aan om het uit te proberen, en belangrijker nog, we horen graag wat je ervan vindt ! Als je een bug vindt, meld deze dan op crbug.com . Voor aanvullende bronnen en tools kun je terecht op use-as-dictionary.com . Tot slot, als je meer wilt weten over hoe het allemaal werkt, is de uitleg een goede volgende stap!