Automatically optimize all <img>
tag assets and replace them with <picture>
elements at build-time.
Reduce your assets payload size by an order of magnitude!
Install the package using your preferred package manager:
# Using npm
npm install --save-dev svelte-preprocess-image-optimize
# Using bun
bun add --dev svelte-preprocess-image-optimize
# Using yarn
yarn add --dev svelte-preprocess-image-optimize
# Using pnpm
pnpm add --save-dev svelte-preprocess-image-optimize
Install vite-imagetools (required peer dependency):
bun add --dev vite-imagetools
Add the preprocessor to your svelte.config.js
:
import { optimizeImagePreprocess } from "svelte-preprocess-image-optimize";
const config = {
preprocess: [
optimizeImagePreprocess(),
// your other preprocessors...
],
};
export default config;
Configure vite-imagetools in your vite.config.js
(see detailed setup below)
Use regular <img>
tags - they'll be automatically optimized to <picture>
elements!
Add the imagetools plugin to your vite.config.js
:
import { defineConfig } from "vite";
import { imagetools } from "vite-imagetools";
const filetypesToOptimize = ["jpg", "jpeg", "png", "gif"];
const outputFiletypes = ["avif", "webp"];
export default defineConfig({
plugins: [
imagetools({
defaultDirectives: (url) => {
let sourceFileType = url.pathname.split(".").pop();
if (filetypesToOptimize.includes(sourceFileType)) {
return new URLSearchParams({
format: `${outputFiletypes.join(';')}${sourceFileType}`,
as: "picture",
});
}
return new URLSearchParams();
},
cache: {
enabled: true,
dir: "./node_modules/.cache/imagetools",
},
}),
// your plugins here... such as `sveltekit()` from @sveltejs/kit/vite
],
});
To modify the array of filetypes that you'd like to be optimized, edit
filetypesToOptimize
. See file types supported by imagetools here. To modify the output optimized image filetypes, editoutputFiletypes
.
Now whenever you import an asset, it will resolve as an object instead of a string.
For example, the following will no longer work:
<script>
import UnoptimizedImage from "$lib/images/unoptimized-image.jpg";
</script>
<img src={UnoptimizedImage} />
Add svelte-preprocess-image-optimize
to your preprocess array in svelte.config.js
:
import { optimizeImagePreprocess } from "svelte-preprocess-image-optimize";
const config = {
kit: {
/* Your adapter here... such as `adapter()` from @sveltejs/adapter-auto */
},
preprocess: [
optimizeImagePreprocess(),
/* Your other preprocessors here... such as `vitePreprocess()` from @sveltejs/vite-plugin-svelte */
],
};
export default config;
Once configured, your <img>
tags will be automatically replaced with optimized <picture>
elements at build-time.
Input:
<img src="/lib/path/to/your/image.jpg" alt="some description" />
Output:
<picture>
<source srcset="/_app/immutable/assets/image.CPwj1ax-.avif" type="image/avif">
<source srcset="/_app/immutable/assets/image.Cuy2wk3m.webp" type="image/webp">
<img src="/_app/immutable/assets/image.DhhxpsQB.jpg" alt="some description">
</picture>
Note: All attributes from the original
<img>
element are preserved on the final<img>
element within the<picture>
.
Vite-imagetools automatically caches optimized images during development for faster rebuilds.
To substantially reduce build times in CI, restore the imagetools cache directory between builds.
Add this step to your workflow after dependency installation but before building:
name: Build and Deploy
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: bun install
- name: Cache imagetools directory
uses: actions/cache@v4
with:
path: ./node_modules/.cache/imagetools
key: imagetools-${{ hashFiles('**/*.png', '**/*.jpg', '**/*.jpeg', '**/*.gif') }}
restore-keys: |
imagetools-
- run: bun run build
magic-string
: ^0.30.0vite-imagetools
: ^7.0.0 (for image processing)MIT License - see LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.