Description
Updated Aug 2023 by @benmccann - this thread has gotten quite long, so I've summarized some key points here. We have some docs on the site (https://kit.svelte.dev/docs/assets) that share some helpful basics. This issue discusses a potential future implementation within SvelteKit
Static optimization with an Image
component
Vite's build pipeline will handle assets that you import
: https://vitejs.dev/guide/assets.html
You can use vite-imagetools
to transform those images as part of Vite's pipeline. E.g. the most common transform might be to generate avif and webp versions of an image. You can use the defaultDirectives
option to set a project-wide default or you can add query parameters to handle images individually. You can also import a directory of images using Vite's import.meta.glob with its query option.
You could use something like bluwy/svelte-preprocess-import-assets to let users simply write img
tags that get converted to import statements for Vite to process.
A discussion of how to set this up is included at #241 (comment) and further demonstrated in #241 (comment).
Static optimization powered by a preprocessor
A problem with using an Image
component in Svelte is that it requires the usage of :global
to style it and it's difficult to handle events on it. It's possible some of these issues could be addressed in Svelte itself (e.g. there was a community proposal regarding event forwarding sveltejs/rfcs#60), but at the current time there are no concrete plans around this.
One solution to this would be to use a preprocessor to convert:
<img alt="delete" src="$lib/icons/trashcan.png" />
Into something like:
<script>
import __image1 from '$lib/icons/trashcan.png';
import __image1_avif from '$lib/icons/trashcan.png?format=avif';
import __image1_webp from '$lib/icons/trashcan.png?format=webp';
</script>
<picture>
<source type="image/avif" src={__image1_avif} />
<source type="image/webp" src={__image1_webp} />
<img alt="delete" src={__image1} width="24" height="24" />
</picture>
This actually scales very well since sveltejs/svelte#8948.
However, this approach doesn't work as well for something like the SvelteKit showcase or import.meta.glob
because it requires the presence of an img
tag.
Dynamic optimization
You could also implement a function to alter a URL and output the CDN's URL (e.g. #10323). Including this manually may become cumbersome, but as with the static optimization case, you could use something like bluwy/svelte-preprocess-import-assets to let users simply write img
tags that get converted to use this function. The unpic library is an example of this approach. This approach works really well when users have a CDN available and some hosts like Vercel have CDNs as included offerings. For users that want to deploy to somewhere like GitHub pages the static approach might work better and so it may make sense to offer dynamic optimzation alongside one of the static optimization approaches.