sveltejs / kit

web development, streamlined
https://svelte.dev/docs/kit
MIT License
18.78k stars 1.96k forks source link

enhanced:img doesn't generate multiple sizes when using dynamically imported image #12609

Open Extarys opened 3 months ago

Extarys commented 3 months ago

Describe the bug

According to the documentation:

If you have a large image, such as a hero image taking the width of the design, you should specify sizes so that smaller versions are requested on smaller devices. E.g. if you have a 1280px image you may want to specify something like:

<enhanced:img src="./image.png" sizes="min(1280px, 100vw)"/>

If sizes is specified, <enhanced:img> will generate small images for smaller devices and populate the srcset attribute.


This doesn't appear to work when the image is loaded dynamically:

Reproduction

Create a component (trimmed):

<script>
let { bgSrc } = $props()
</script>
<enhanced:img src={bgSrc}
   sizes="min(800px, 1900px)" />

From a page:

    import heroBgSrc from "$static/stock/bg.jpg?enhanced"
...
    <Hero bgSrc={heroBgSrc} />

Result:

<picture>
<source srcset="/@imagetools/f4bde5cce2511ff9615b0db6e65acb41672eed99 4142w, /@imagetools/6edc3aef7c7ad5b939438aade22388525cd27d51 8284w" sizes="min(800px, 1900px)" type="image/avif">
<source srcset="/@imagetools/9b20960ece0d072aff909ed0412b8c27d4ffbf28 4142w, /@imagetools/32e33bfd0bb5ffb8887de23921ee4bf760582417 8284w" sizes="min(800px, 1900px)" type="image/webp">
<source srcset="/@imagetools/07b72a21665d5252b5c52ebbfcb19943d299f76d 4142w, /@imagetools/e82c9351d6bba21db8d71d462b3359bb5d447320 8284w" sizes="min(800px, 1900px)" type="image/jpeg">
<img src="/@imagetools/e82c9351d6bba21db8d71d462b3359bb5d447320" svelte-vleyz1" width="8284" height="4955">
</picture>

Logs

None

System Info

System:
    OS: Linux 6.10 Fedora Linux 40 (KDE Plasma)
    CPU: (24) x64 AMD Ryzen 9 5900X 12-Core Processor
    Memory: 42.03 GB / 62.68 GB
    Container: Yes
    Shell: 5.2.26 - /bin/bash
  Binaries:
    Node: 20.12.2 - /usr/bin/node
    Yarn: 1.22.22 - /usr/bin/yarn
    npm: 10.5.0 - /usr/bin/npm
    bun: 1.1.20 - ~/.bun/bin/bun
  npmPackages:
    svelte: ^5.0.0-next.1 => 5.0.0-next.192

Severity

annoyance

Additional Information

I hope this is how it is intended to be used, the docs seem to say so, but I'm quite a beginner at this.

artemkovalyov commented 3 days ago

Yeah, dynamic images are complicated. I managed to make it work more or less with this approach by providing addition query parameters.

const images = import.meta.glob('/src/**/*.{jpg,jpeg,png,gif,pdf}', {
  eager: true,
  query: {
    enhanced: true,
    w: '1280;640;400' // here you request the sizes you need
  }
});

Or if you have a static import somewhere, you still need enhance it with similar query parameters to then use that object in the enhanced image:

<enhanced:img
          src={imageSrc}
          alt="woop woop"
          sizes="(min-width:1920px) 1280px, (min-width:1080px) 640px, (min-width:768px) 400px"
        />
artemkovalyov commented 3 days ago

You can also run this on the generated bundle: https://github.com/divriots/jampack