Komprimer filer i nett­leseren, uten avhengig­heter: «Ingenting er så fantastisk»

– Jeg håper folk får ånden over seg, og fjerner avhengigheter til JSZip, skriver Martin Klingenberg om et innebygd nettleser-API for å komprimere filer: CompressionStream.

Martin Klingenberg er frontendsjef i Alv. 📸: Kurt Lekanger
Martin Klingenberg er frontendsjef i Alv. 📸: Kurt Lekanger Vis mer

De av oss som har hatt behov for å komprimere filer og tekst på frontenden har frem til 2023 vært avhengig av eksterne biblioteker.

Nå er CompressionStream-interfacet tilgjengelig på tvers av alle nettlesere. Jeg snublet over denne featuren da jeg hadde behov for å komprimere filer. Det er noe jeg svært sjelden har behov for når jeg skriver frontendkode.

Jeg ble positivt overrasket da jeg innså at jeg ikke trengte å legge til et bibliotek for å gzippe en fil. CompressionStreams lar deg komprimere filer og tekst med tre forskjellige algoritmer: deflate, deflate-raw eller gizp.

CompressionStream og async iterators

Eksemplet under tar inn en fil og returnerer en Blob.

Vi lager en stream som sendes gjennom en CompressionStream, etterfulgt av at vi looper igjennom dataene, for å så lage en Blob:

Hvordan komprimere en fil i javascript, helt uten avhengigheter
Hvordan komprimere en fil i javascript, helt uten avhengigheter Vis mer

Nå må man loope gjennom med en while-loop.

I Chrome og Firefox kan man bruke async iteratorsreadable streams. Det er en skikkelig kul feature som ikke har kommet til Safari ennå.

Se hvor mye enklere det blir å lese koden:

Se hvor mye enklere koden kan bli om Safari gjør det mulig å bruke Async Iterators på ReadableStreams.
Se hvor mye enklere koden kan bli om Safari gjør det mulig å bruke Async Iterators på ReadableStreams. Vis mer

Ytelsen på komprimeringen

Nå har jeg bare testet CompressionStream med Excel-ark. Da har jeg oppnådd omtrent halv filstørrelse (49,5%). Det synes jeg er utrolig bra.

Det er en del use-cases jeg kommer på. Om man har en tjeneste der man skal laste opp bilder, lyd eller lignende fra mobilen, så vil dette gjøre brukeropplevelsen mye bedre.

Om du lurer på hvilket kompresjons-nivå man får, så har jeg testet meg frem til at det tilsvarer å kjøre gzip -v4 inputfile. Dette er testet med Firefox. Det vil kunne variere fra nettleser til nettleser.

Hvor god er nettleserstøtten?

Støtten er det som MDN kaller "Widely Available".

En rask sjekk på caniuse.com viser at dette interfacet er støttet av 90.64% av nettleserne der ute. Av de 9.36% som ikke kan bruke dette interfacet, så er majoriteten av disse nettleserne gamle versjoner av Safari og Internet Explorer.

Om du skulle ha behov for å dekke absolutt alle nettlesere, så finnes det en polyfill som bare øker din bundlesize med 17 kB. Dette er uansett bedre enn å bruke jsZip-biblioteket, som vil øke bundle size med 94 kB.

Bli kvitt teknisk gjeld

Jeg håper folk får ånden over seg, og fjerner avhengigheter til JSZip og tilsvarende biblioteker.

Ingenting er så fantastisk som å kunne fjerne unødvendige avhengigheter.

Kommenter gjerne under om du har brukt CompressionStreams eller om du kommer til å starte å bruke dem nå.