Why should you care?
Uncompressed images bloat your pages with unnecessary bytes. Because images can be candidates for Largest Contentful Paint (LCP), those unnecessary bytes can increase the image's resource load duration, possibly resulting in longer LCP times.
The photo on the right is 40% smaller than the one on the left, yet would probably look identical to the average user.
20 KB | 12 KB |
---|
Measure
Run Lighthouse to check for opportunities to improve page load by compressing images. These opportunities are listed under "Efficiently encode images":
Imagemin
Imagemin is an excellent choice for image compression because it supports a wide variety of image formats and is easily integrated with build scripts and build tools. Imagemin is available as both a CLI and an npm module. Generally, the npm module is the best choice because it offers more configuration options, but the CLI can be a decent alternative if you want to try Imagemin without touching any code.
Plugins
Imagemin is built around "plugins." A plugin is an npm package that compresses a particular image format (e.g. "mozjpeg" compresses JPEGs). Popular image formats may have multiple plugins to pick from.
The most important thing to consider when choosing a plugin is whether it is "lossy" or "lossless." In lossless compression, no data is lost. Lossy compression reduces file size, but at the expense of possibly reducing image quality. If a plugin doesn't mention whether it is "lossy" or "lossless," you can tell by its API: if you can specify the image quality of the output, then it is "lossy."
For most people, lossy plugins are the best choice. They offer significantly greater filesize savings, and you can customize the compression levels to meet your needs. The table below lists popular Imagemin plugins. These aren't the only plugins available, but they'd all be good choices for your project.
Image Format | Lossy Plugin(s) | Lossless Plugin(s) |
---|---|---|
JPEG | imagemin-mozjpeg | imagemin-jpegtran |
PNG | imagemin-pngquant | imagemin-optipng |
GIF | imagemin-giflossy | imagemin-gifsicle |
SVG | imagemin-svgo | |
WebP | imagemin-webp | imagemin-webp |
Imagemin CLI
The Imagemin CLI works with 5 different plugins: imagemin-gifsicle, imagemin-jpegtran, imagemin-optipng, imagemin-pngquant, and imagemin-svgo. Imagemin uses the appropriate plugin based on the image format of the input.
To compress the images in the "images/" directory and save them to the same directory, run the following command (overwrites the original files):
$ imagemin images/* --out-dir=images
Imagemin npm module
If you use one of these build tools, checkout the codelabs for Imagemin with webpack, gulp, or grunt.
You can also use Imagemin by itself as a Node script. This code uses the "imagemin-mozjpeg" plugin to compress JPEG files to a quality of 50 ('0' being the worst; '100' being the best):
const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
(async() => {
const files = await imagemin(
['source_dir/*.jpg', 'another_dir/*.jpg'],
{
destination: 'destination_dir',
plugins: [imageminMozjpeg({quality: 50})]
}
);
console.log(files);
})();