# Qwik Image Optimization Brainstorming Doc
- https://github.com/BuilderIO/qwik/issues/1460
## Overview
The goal is to implement two things:
- An Image REST API which would be part of the Qwik-City which would allow
- `<Image>` component which will take a URL and optimize it for the current window size.
General overview:
1. Qwik-city application will place original images in the `/public` folder. (Let's assume `/public/hero/outdoors.jpg`.)
2. A rest API can be used to retrieve the image on `/img/[...path]` (`/img/hero/outdoors.jpg` would retrieve the image.)
3. The `/img/[...path]` REST service would set the header such that the image can be resized; converted to other formats; and cached.
4. The `<Image>` tag can be used to modify the URL query parameters to request a different encoding, size, caching strategy.
## Mental Model
1. Have a route out of the box which can do image resizing (this is why wasm would be important)
2. Have CDN in front of it to handle most of the downloads
3. Have Vite plugin which generates image metadata so that it can be used in QwikCity components
4. Have a configuration file which would easily allow you to switch from out-of-the box solution to Claudinary etc
## Developer usage
For best caching performance it would be best of the `<Image>` can contain the content hash (or other things such as blur). To do this we can have a vite plugin which will automatically wrap any image in the `<Image src="hero/outdoors.jpg" hash="1234"/>`.
```typescript!
import {component$} from '@builder.io/qwik';
import HeroImage from '/public/hero/outdoors.jpg';
export const component$(() => {
return <HeroImage/>;
});
```
NOTE: Referring to images through dynamic URLs is still possible but requires different cache strategies as the HTML would not know the hash of the image and hence may serve stale images.
## Work breakdown
1. REST API
2. Configuration File
- `Image <= CloudinaryImage`
- Breakpoints
4. Vite Plugin
- `<HeroImage> => <Image src="/builic/hero.jpe" aspect={1} hash='ABC' />`
5. `<Image>` component
- loader
- src
- alt
- width
- height
- class ?
## Related projects to explore
- https://www.libvips.org/2020/09/01/libvips-for-webassembly.html
- https://github.com/silvia-odwyer/photon
- https://github.com/jupiter/rust-image-worker
- https://www.npmjs.com/package/sharp (https://unpkg.com/browse/sharp@0.31.2/package.json)
### Sample Qwik Component
```typescript
import { component$, Image } from '@builder.io/qwik';
const myLoader = ({ src, width, quality }) => {
return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}
const MyImageCmp = component$((props) => {
return (
<Image
loader={myLoader}
src="me.png"
alt="Picture of the author"
width={500}
height={500}
/>
))
}
```
### Sample Config
```typescript
const config = {
images: {
deviceSizes: [
144,
164,
184,
208,
234,
303,
358,
440,
488,
503,
524,
606,
640,
716,
750,
766,
828,
880,
1080,
1200,
1920,
2048,
3840
],
imageSizes: [
16,
32,
48,
64,
96,
128,
256,
384
],
formats: ['image/avif', 'image/webp'],
minimumCacheTTL: 60,
domains: [
'images.unsplash.com',
'lh3.googleusercontent.com',
's.gravatar.com',
],
},
}
```