What is the Compression Streams API?

•

Mon Mar 20 2023

•

6 min read

As our world becomes increasingly digital, efficient data compression has become an essential tool for reducing storage requirements. There are multiple tools out there to help you with it but there is also an API that can compress data for you.

The Compression Streams API is a powerful Web API that you can use to implement compression and decompression functionality in your applications.

So without further ado, let's look into the Compression Streams API.

Compression Stream API

This API provides a set of classes and methods that enable you to compress and decompress data in a variety of formats. Let's take a closer look at the key features and functionality of the Compression Streams API.

Basic functionality

The main function of this API is that it enables you to create compression streams that wrap around existing input and output streams. These compression streams can then be used to compress or decompress data as it is read from or written to the underlying streams.

Compression algorithms

The Compression Streams API supports a variety of compression algorithms, including Deflate and GZip. Deflate is a widely used algorithm that provides a good balance between compression ratio and speed. GZip is a popular format for compressing files and generally provides better compression than Deflate.

Decompression algorithms

In addition to compression algorithms, this API also supports a range of decompression algorithms. These include the same algorithms used for compression, such as Deflate, GZip, etc.

Usage

Let's take a look at how to use this API in an application.

Setup

To use this API in your project, you need to ensure that your environment supports it. It is supported by most modern web browsers, including Google Chrome, Mozilla Firefox, and Microsoft Edge.

Creating a Compression Stream

First, you need to instantiate a CompressionStream object with the desired compression algorithm. For example, to create a CompressionStream that uses the GZip algorithm, you would use the following code:

js
const compressionStream = new CompressionStream('gzip');

Compressing Data

Once you have a compression stream, you can use it to compress data. To do this, you need to pipe the input data to the compression stream, and then read the compressed data from the output of the stream. Here is an example of how to compress data using the GZip algorithm:

js
const readableStream = await fetch('file.txt').then(
(response) => response.body
);
const compressedReadableStream = readableStream.pipeThrough(
new CompressionStream('gzip')
);

Here, we are using the Fetch API to obtain a readable stream from a file called "file.txt". Then, we create a new CompressionStream object with the gzip algorithm to compress the data from the readable stream. Finally, we are piping the compressed data into a new readable stream called compressedReadableStream.

Creating a Decompression Stream

First, you need to instantiate a DecompressionStream object with the desired decompression algorithm. For example, you would do something like this:

js
const decompressionStream = new DecompressionStream('gzip');

Decompressing Data

To decompress data, you need to pipe the compressed data to the decompression stream, and then read the decompressed data from the output of the stream. Here is how:

js
const decompressionStream = new DecompressionStream('gzip');
const decompressedReadableStream = compressedReadableStream.pipeThrough(decompressionStream);
);

Handling errors

You can handle errors with the Compression Streams API by adding a try-catch block around the code that uses the API. Here’s an example:

js
try {
const readableStream = await fetch('file.txt').then(
(response) => response.body
);
const compressedReadableStream = readableStream.pipeThrough(
new CompressionStream('gzip')
);
// compressedReadableStream code
} catch (error) {
console.error('Error compressing data:', error);
}

Example

Using the things we learned above, let’s use this API in real time.

Step #1: Create an HTML file

Create a new HTML file and add the necessary boilerplate code.

html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Compression Streams API Example</title>
</head>
<body>
</body>
</html>

Step #2: Import necessary function

Now let’s import the fileSave method. This is used to save the compressed file as a new file on the user’s system.

js
import { fileSave } from 'https://unpkg.com/browser-fs-access@0.31.0/dist/index.modern.js';

Step #3: Create UI element

We need to create an input element and a button. So let’s do that.

js
<input type="file" id="file-input">
<button id="compress-button">Compress File</button>

Step #4: Reference the elements

Now we need to get the reference of the input field and the button that we created in last step.

html
<!DOCTYPE html>
<html>
<head>
<title>Compress File Demo</title>
</head>
<body>
<input type="file" id="file-input">
<button id="compress-button">Compress File</button>
<script type="module">
import { fileSave } from 'https://unpkg.com/browser-fs-access@0.31.0/dist/index.modern.js';
const fileInput = document.getElementById('file-input');
const compressButton = document.getElementById('compress-button');
</script>
</body>
</html>

Step #5: Handling user input

We will now create an async function called handleFileInput.This function will be called whenever a file is selected. It will read the contents of the file, compress it, and save the compressed file to the user's local system.

js
async function handleFileInput() {
const file = fileInput.files[0];
if (!file) return;
const compressedFile = await compressFile(file);
console.log('Compressed file:', compressedFile);
}

Step #6: Use Compression Streams API

Now we will create a new function called compressFile where we use the Compression Streams API that we learned earlier.

js
async function compressFile(file) {
const readableStream = await file.stream();
const compressedReadableStream = readableStream.pipeThrough(new CompressionStream('gzip'));
const compressedFile = await fileSave(new Response(compressedReadableStream), {
fileName: file.name + '.gz',
extensions: ['.gz'],
});
return compressedFile;
}

Step #7: Add event listener

Lastly, add an event listener to the compress button that will trigger the compressFile function when clicked.

js
compressButton.addEventListener('click', async () => {
const file = fileInput.files[0];
if (!file) return;
const compressedFile = await compressFile(file);
console.log('Compressed file:', compressedFile);
});

And that's it! You now have a web app that allows users to select a file and compress its contents using the Compression Streams API.

Here is the entire code:

html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Compression Streams API Example</title>
</head>
<body>
<input type="file" id="file-input">
<button id="compress-button">Compress File</button>
<script type="module">
// Import the functions
import { fileSave } from 'https://unpkg.com/browser-fs-access@0.31.0/dist/index.modern.js';
// Get references to the file input and compress button elements
const fileInput = document.getElementById('file-input');
const compressButton = document.getElementById('compress-button');
// Listen for changes to the file input element
fileInput.addEventListener('change', handleFileInput);
// Define the function that will handle the file input change event
async function handleFileInput() {
// Get a reference to the selected file
const file = fileInput.files[0];
if (!file) return;
// Compress the selected file and save it
const compressedFile = await compressFile(file);
console.log('Compressed file:', compressedFile);
}
// Define the function that will compress the selected file
async function compressFile(file) {
// Convert the file to a readable stream
const readableStream = await file.stream();
// Create a new compression stream and pipe the readable stream through it
const compressedReadableStream = readableStream.pipeThrough(new CompressionStream('gzip'));
// Save the compressed stream as a new file and return the new file object
const compressedFile = await fileSave(new Response(compressedReadableStream), {
fileName: file.name + '.gz',
extensions: ['.gz'],
});
return compressedFile;
}
// Listen for clicks on the compress button element
compressButton.addEventListener('click', handleFileInput);
</script>
</body>
</html>

You can also add the decompressing functionality in the code.

Wrap Up

By using Compression Stream API, we can easily compress and decompress files in real-time without needing to upload them to a server. This allows for faster and more efficient file handling.

If you want to learn more about compression, we have a piece on HTTP compression explaining how it makes your website faster than before.