Features:
- Optimize images using WebAssembly (runs in every environment)
- Image manipulation provided by various query params (resize, converting, low quality placeholders, ...)
- Build cache for images for faster builds
- Convert to WebP automatically during a webpack build
- Inline small images automatically
- ...
npm install optimized-images-loader
Add the loader to your webpack configuration:
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg|webp)$/i,
use: [
{
loader: 'optimized-images-loader',
options: {
// see below for available options
},
},
],
},
],
},
};
Option | Default | Type | Description |
---|---|---|---|
limit | 8192 |
number |
Images smaller than this number (in bytes) will get inlined with a data-uri. |
optimize | true |
boolean |
If this plugin should not optimized images, set this to false . You can still resize images, convert them to WebP and use other features in that case. |
cacheFolder | 'node_modules/optimized-images-loader/.cache' |
string |
Images will be cached in this folder to avoid long build times. |
includeStrategy | string |
'string' |
When using the ?include query param, it returns a string by default. By setting this value to 'react' , it returns a React component instead (requires manually installing the additional @svgr/core package). |
name | '[name]-[contenthash].[ext]' |
string |
File name of the images after they got processed. Additionally to the default placeholders, [width] and [height] are also available. |
outputPath | string |
Images will be saved in this directory instead of the default webpack outputPath. | |
publicPath | string |
The public path that should be used for image URLs instead of the default webpack publicPath. | |
mozjpeg | MozjpegOptions |
Specifies the options used to optimize jpeg images. All available options can be seen here. | |
oxipng | OxipngOptions |
Specifies the options used to optimize png images. All available options can be seen here. | |
webp | WebpOptions |
Specifies the options used to optimize webp images. All available options can be seen here. | |
svgo | SvgoOptions |
Specifies the options used to optimize svg images. All available options can be seen here. |
You can now simply import images in your projects the same way as you would import source code.
import Header from './images/header.jpg';
export default () => (
<div>
<img src={Header} />
</div>
);
This loader also provides a variety of query params to provide you even more options:
?include
: Include the raw file directly (useful for SVG icons)?webp
: Convert an image to WebP on the fly?inline
: Force inlining an image (data-uri)?url
: Force an URL for a small image (instead of data-uri)?original
: Use the original image and do not optimize it?lqip
: Generate a low quality image placeholder?colors
: Extract the dominant colors of an image?width
: Resize an image to the given width?height
: Resize an image to the given height?trace
: Use traced outlines as loading placeholder (currently not supported)?sprite
: Use SVG sprites (currently not supported)
The image will now directly be included in your HTML without a data-uri or a reference to your file.
By default, it will be included as a normal string
. If you are in a React project and wish to transform it into a React component, set the includeStrategy
to 'react'
and run npm install @svgr/core
.
If this ?webp
query parameter is specified, optimized-images-loader
automatically converts the image to the new WebP format.
For browsers that don't yet support WebP, you may want to also provide a fallback using the <picture>
tag or use the Img
component which does this out of the box:
You can specify a limit for inlining images which will include it as a data-uri directly in your content instead of referencing a file if the file size is below that limit.
You usually don't want to specify a too high limit but there may be cases where you still want to inline larger images.
In this case, you don't have to set the global limit to a higher value but you can add an exception for a single image using the ?inline
query options.
When you have an image smaller than your defined limit for inlining, it normally gets inlined automatically.
If you don't want a specific small file to get inlined, you can use the ?url
query param to always get back an image URL, regardless of the inline limit.
The image won't get optimized and used as it is. It makes sense to use this query param if you know an image already got optimized (e.g. during export) so it doesn't get optimized again a second time.
When using this resource query, a very small (about 10x10 pixel) image gets created. You can then display this image as a placeholder until the real (big) image has loaded.
This resource query returns you an array with hex values of the dominant colors of an image. You can also use this as a placeholder until the real image has loaded (e.g. as a background) like the Google Picture Search does.
The number of colors returned can vary and depends on how many different colors your image has.
import React from 'react';
export default () => (
<div style={{ backgroundColor: require('./images/my-image.jpg?colors')[0] }}>...</div>
);
/**
* require('./images/my-image.jpg?colors')
*
* returns for example
*
* ['#0e648d', '#5f94b5', '#a7bbcb', '#223240', '#a4c3dc', '#1b6c9c']
*/
Currently not supported
With the ?trace
resource query, you can generate SVG image outlines which can be used as a placeholder while loading the original image.
Resizes the source image to the given width. If a height is additionally specified, it ensures the image covers both sizes and crops the remaining parts. If no height is specified, it will be automatically calculated to preserve the image aspect ratio.
import React from 'react';
import Image from './images/my-image.jpg?width=800';
import Thumbnail from './images/my-image.jpg?width=300&height=300';
export default () => (
<div>
<img src={Image} />
<img src={Thumbnail} />
</div>
);
Resizes the source image to the given height. If a width is additionally specified, it ensures the image covers both sizes and crops the remaining parts. If no width is specified, it will be automatically calculated to preserve the image aspect ratio.
import React from 'react';
import Image from './images/my-image.jpg?height=800';
import Thumbnail from './images/my-image.jpg?width=300&height=300';
export default () => (
<div>
<img src={Image} />
<img src={Thumbnail} />
</div>
);
Currently not supported
TODO: needs general documentation
Licensed under the MIT license.
© Copyright Cyril Wanner