Verbeter de compressie-efficiëntie met gedeelde woordenboeken

Gegevenscompressie is een beproefde techniek voor prestatie-optimalisatie die de omvang van in aanmerking komende paginabronnen verkleint. Het was enige tijd gebruikelijk om gzip voornamelijk op webservers te gebruiken om algemene op tekst gebaseerde 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 zeer effectief is, zijn er de afgelopen jaren verdere verbeteringen in de compressie op internet gerealiseerd. In 2016 werd het Brotli-algoritme in Chrome uitgebracht, wat over het algemeen betere compressieverhoudingen opleverde voor in aanmerking komende bronnen. Eind 2017 ondersteunden alle moderne browsers Brotli, en de serverondersteuning ervoor begon steeds wijdverspreider te worden. Meer recentelijk heeft Chrome ZStandard-compressie geleverd .

Het werk stopt daar echter niet! Het Chrome-team heeft gewerkt aan het bruikbaar maken van gedeelde woordenboeken op internet, die nu beschikbaar zijn in een origin-proefversie voor zowel Brotli als ZStandard . Gedeelde woordenboeken kunnen de Brotli- en ZStandard-compressie aanvullen om substantieel hogere compressieverhoudingen te leveren voor websites die regelmatig bijgewerkte code leveren, en kunnen in sommige gevallen 90% of betere compressieverhoudingen leveren. Dit bericht gaat dieper in op hoe gedeelde woordenboeken werken en hoe u zich kunt registreren voor de origin-proeven om ze voor Brotli en ZStandard op uw website te gebruiken.

Gedeelde woordenboeken uitgelegd

Compressie is een proces waarbij overtollige reeksen 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 internet omdat het de laadtijden van bronnen aanzienlijk verkort. Zowel Brotli als ZStandard kunnen hun effectiviteit verder vergroten door een compressiewoordenboek te gebruiken, een verzameling aanvullende patronen die deze algoritmen tijdens compressie kunnen gebruiken. In feite wordt de hoge efficiëntie van Brotli tot op zekere hoogte bereikt door een intern woordenboek te gebruiken.

Er kunnen echter aangepaste , door de gebruiker samengestelde woordenboeken 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 welke inhoud dan ook. Hoe toepasbaar een bepaald woordenboek is op zijn invoer, kan een grote impact hebben op de algehele compressie-efficiëntie. Woordenboeken die sterk lijken op de inhoud van een invoer zullen uitvoer opleveren met hogere compressieverhoudingen dan woordenboeken met algemene of ongelijksoortige inhoud.

Hier is een voorbeeld van hoe effectief een aangepast compressiewoordenboek kan zijn: stel dat uw website het Angular-framework gebruikt en dat de huidige versie die u gebruikt versie 1.7.9 is. Deze versie van het Angular-framework is ongecomprimeerd ongeveer 172 KiB. Wanneer gecomprimeerd met de standaardinstellingen van Brotli, wordt de grootte ongeveer 53 KiB. Dit levert een compressieverhouding van bijna 70% op. Stel echter dat u later besluit om te upgraden naar Angular 1.8.3. Aangezien deze versie van Angular ongeveer even groot is als versie 1.7.9, kun je 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 bekend staat als deltacompressie . Dit is wanneer een woordenboek van een eerdere versie van een bron kan worden gebruikt om een ​​latere versie te comprimeren. Als u het vorige voorbeeld gebruikt: als u versie 1.8.3 van Angular comprimeerde met versie 1.7.9 als woordenboek, zou de uitvoer iets meer dan 4 KiB bedragen. Dit vertegenwoordigt een compressieverhouding van bijna 98% . Het is duidelijk dat compressiewoordenboeken een grote impact kunnen hebben op de laadprestaties, en hun effectiviteit is al gerealiseerd in toepassingen in de echte wereld !

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

Hoe Chrome ondersteuning voor gedeelde woordenboeken adverteert

Alle browsers maken reclame voor de compressie-algoritmen die ze ondersteunen via de Accept-Encoding request header . 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 bron opvraagt ​​de compressie-algoritmen gzip, Brotli en ZStandard ondersteunt. Een webserver die op het verzoek reageert, kan vervolgens beslissen welk algoritme moet worden gebruikt bij het reageren op het verzoek.

Wanneer ondersteuning voor gedeelde woordenboeken is ingeschakeld en er een relevant woordenboek beschikbaar is voor een bron, worden extra tokens toegevoegd aan de Accept-Encoding header. Deze tokens zijn br-d voor Brotli en zstd-d voor Zstandard. Chrome zal ook de hash van een beschikbaar woordenboek bevatten, die hierna wordt behandeld.

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 hij op dat verzoek reageren met een bron die is gecomprimeerd met behulp van het woordenboek voor de toepasselijke codering. Hoe dit in de praktijk wordt bereikt, hangt af van het feit of het verzoek om een ​​statisch of dynamisch hulpmiddel gaat.

Gedeelde woordenboekcompressie voor statische bronnen

Een statische paginabron is een paginabron die altijd hetzelfde antwoord produceert voor een opgevraagde URL. Veelvoorkomende voorbeelden van samendrukbare statische paginabronnen zijn JavaScript- en CSS-bestanden. Deze bronnen worden doorgaans op de een of andere manier voorzien van een versie voor cachedoeleinden, soms met een hash van de inhoud van het bestand in de bestandsnaam (bijvoorbeeld styles.abcd1234.css ), of een andere methode om vingerafdrukken van de bron te maken. Deze typen bronnen zijn een uitstekende kandidaat voor de deltacompressie die gedeelde woordenboeken bieden, omdat statische bronnen vaak gedurende langere tijd in de cache worden opgeslagen en de neiging hebben om met enige regelmaat te worden bijgewerkt.

Een woordenboek kan worden opgegeven voor een statische bron door de antwoordheader Use-As-Dictionary ervoor in te stellen. De header gebruikt een van de weinige sleutel/waarde-paren, maar de enige vereiste is match , die de URLPattern syntaxis accepteert die het bronpad 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 bron die overeenkomen met het daarin gespecificeerde patroon. Stel dat uw website alle stijlen in één CSS-bestand verzendt. Laten we voor de eenvoud zeggen dat de eerste versie van die bron zich bevindt op /dist/styles.v1.css en wordt verzonden met een Use-As-Dictionary antwoordheader met daarin een match van /dist/styles.*.css .

Na enige tijd werkt u de CSS van uw website bij en verzendt u een nieuwe versie ervan op /dist/styles.v2.css . Omdat de match die werd gebruikt in de Use-As-Dictionary antwoordheader van de vorige versie van toepassing is op dit verzoek, verzendt de browser een Available-Dictionary header met daarin 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 de compressie aan zijn kant te configureren om ervoor te zorgen dat het overeenkomende 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 vaak 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 browsercache van de gebruiker, worden de extra br-d of zstd-d tokens niet gespecificeerd in de Accept-Encoding header. In dat geval geldt de standaard compressiestroom.

Gedeelde woordenboekcompressie voor dynamische bronnen

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

Vanwege de aard van dynamisch gegenereerde bronnen moet er 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. In dergelijke gevallen hoopt u dat uw website voldoende verkeer ontvangt, zodat de woordenboekkosten kunnen worden afgeschreven over een groot aantal navigatiebezoeken. Mocht u besluiten het te proberen, dan is de eerste stap het specificeren van de locatie van het woordenboek door middel van een <link> -element in de HTML van uw pagina:

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

Wanneer Chrome dit <link> -element tegenkomt, kan het het woordenboek ophalen zodra de pagina inactief is en een lage prioriteit heeft, in een poging bandbreedteconflicten te voorkomen. Het antwoord voor het woordenboek zelf moet een Use-As-Dictionary header specificeren en specificeren 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 zal zien dat het woordenboek zelf van toepassing is op overeenkomende bronnen, en de browser zal een Available-Dictionary header aan het verzoek koppelen met een hash van de inhoud van het woordenboek, opnieuw vergelijkbaar met de statische bronnenstroom die eerder werd uitgelegd.

Comprimeer statische bronnen tijdens het bouwen

Als u bekend bent met bundelaars, kent u mogelijk verschillende plug-ins daarvoor die bronnen tijdens het bouwen kunnen comprimeren en vervolgens deze gecomprimeerde bronnen kunnen bedienen. Met Apache kunt u bijvoorbeeld richtlijnen gebruiken om die vooraf gecomprimeerde bronnen te bedienen op het moment van het verzoek.

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

Houd er rekening mee dat beschikbare woordenboeken voor een bepaalde versie van een bron een van alle voorgaande versies van een bron kunnen gebruiken. Dit betekent dat u het gebruikersverkeer moet analyseren en dienovereenkomstig moet plannen. Streef naar een evenwicht en genereer middelen die het maximale aantal terugkerende gebruikers zo goed mogelijk ten goede komen. CDN-providers experimenteren momenteel met gedeelde woordenboekcompressie. Er zijn nog geen implementaties beschikbaar voor publiek gebruik, maar we verwachten dat daar verandering in komt!

Probeer het!

Het integreren van gedeelde woordenboekcompressie met de bestaande compressiemogelijkheden van de browser heeft het potentieel om de laadprestaties aanzienlijk te verbeteren voor websites die regelmatig bijgewerkte productiecode verzenden en aanzienlijk verkeer ontvangen van terugkerende bezoekers. Als u gedeelde woordenboekcompressie een kans wilt geven, heeft u twee opties:

  1. Als u zelf wilt sleutelen aan gedeelde woordenboekcompressie om een ​​idee te krijgen van hoe het werkt, kunt u de experimentele functie Compressiewoordenboektransport inschakelen op de chrome://flags pagina.
  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-proefversie om een ​​token te krijgen en lees hoe origin-proefversies werken .

Conclusie

We zijn erg enthousiast over deze grote vooruitgang in de compressietechnologie op internet, en hoeveel sneller bestaande toepassingen die mensen dagelijks gebruiken hierdoor kunnen worden gemaakt. We moedigen u aan om het uit te proberen, en het allerbelangrijkste: we willen graag uw mening horen als u dat doet! Als u een bug vindt, kunt u deze melden op crbug.com . Ga voor aanvullende bronnen en hulpmiddelen naar use-as-dictionary.com . Tenslotte, als je geïnteresseerd bent in een diepere duik in hoe het allemaal werkt, is de uitleger een goede volgende stap!