Images take more than a half of the size of an average page:
That’s a lot of traffic! But with webpack, it’s easy to decrease it.
1. Inline small PNG, JPG and GIF images#
Use url-loader
to embed small PNG, JPG and GIF images into the bundle.
url-loader
converts a file (if it’s smaller than the specified size) into a Base64 URL and inserts this URL into the bundle. This helps to avoid extra image requests (which is useful even with HTTP/2).
The limit of 5-10 KB is OK:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif)$/,
loader: 'url-loader',
options: {
// Images larger than 10 KB won’t be inlined
limit: 10 * 1024
}
}
]
}
};
2. Inline small SVG images#
Use svg-url-loader
to embed small SVG images.
This loader works like url-loader
, but it encodes files using the URL encoding instead of the Base64 one. Because SVG is text, the result of the URL encoding is smaller.
The limit of 5-10 KB is also OK:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
loader: 'svg-url-loader',
options: {
// Images larger than 10 KB won’t be inlined
limit: 10 * 1024,
// Remove quotes around the encoded URL –
// they’re rarely useful
noquotes: true,
}
}
]
}
};
3. Optimize image size#
Use image-webpack-loader
to make images smaller.
This loader compresses PNG, JPG, GIF and SVG images by passing them through optimizers. Since it just pipes images through itself and doesn’t insert them into the bundle, it should be used with url-loader
/svg-url-loader
.
The default loader settings are OK:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(jpg|png|gif|svg)$/,
loader: 'image-webpack-loader',
// Specify enforce: 'pre' to apply the loader
// before url-loader/svg-url-loader
// and not duplicate it in rules with them
enforce: 'pre'
}
]
}
};
Questions#
“Why is this important?”
As I’ve said, images take more than 50% of the average page size, and optimizing them is super-easy. Through, at the same time, I’ve rarely seen webpack configs that do it. We seriously should always optimize them.
“What should I do?”
Go and add these loaders to your config.
“Are the any side effects?”
A couple:
image-webpack-loader
increases the build time, so it’s better to disable it during development (pass thebypassOnDebug: true
option to do that)-
url-loader
andsvg-url-loader
remove extra image requests, but break caching of these images and increase the JS loading/parsing time and memory consumption. If you inline large images or lots of images, you might experience issues. (Thanks to Addy Osmani for noting this.)
Further reading#
- Addy Osmani’s excellent guide on image optimization
- My article about optimizing bundle size with webpack