do not set default values for loading, decoding, etc
I believe you may be overriding the browser's ability to discern what is best by having default values for loading and decoding:
https://github.com/zerodevx/svelte-img/blob/master/src/lib/SvelteImg.svelte#L13-L16
As far as I understand how it's supposed to work, I believe it's best to leave these unset so the browser can make its own educated decision. Same with fetchpriority, if you were to add that.
As it currently stands, these values will always be set, and the browser will have no ability to discern on its own.
believe you may be overriding the browser's ability to discern
Ooh I'll have to read on that one. IIRC if loading is left unset, it defaults to eager.
If browsers now automatically prioritises above-the-fold images and lazily-loads the rest, then certainly we should remove the default overrides.
From a user experience perspective, what kills is the page jumping (reflowing/cumulative layout shift) when an image gets loaded, rather than how quickly it's loaded (that's what the LQIP is for). But page jumps are a solved problem because image dimensions are now explicitly set. I know Lighthouse penalises lazily-loaded above-the-fold images, but in many cases that's the developer's intention, because images are not the main content (the words are).
I think loading makes sense. Probably doesn't hurt to set decoding, but don't think it really helps?
Maybe I was thinking more along this line regarding preload when I made the OP:
Again this should be used sparingly to avoid overriding the browsers prioritisation heuristics too much, which may result in performance degredation.
https://web.dev/learn/design/responsive-images#preloading_hints
(and some other discussions I saw that future browsers could/should be smarter about loading images without our help)
Regarding decoding here is some good info:
https://web.dev/learn/design/responsive-images#preloading_hints
The decoding attribute will not change how fast the image decodes, but merely whether the browser waits for this image decoding to happen before rendering other content.
In most cases this will have little impact, however in certain scenarios it can allow the image or content to be displayed slightly faster. For example, for a large document with lots of elements that take time to render, and with large images that take a while to decode, setting sync on important images will tell the browser to wait for the image and render both at once. Alternatively, setting async can allow the content to be displayed faster without waiting for the image decode.
However, the better option is usually to try to avoid excessive DOM sizes and ensure responsive images are used to reduce decoding time meaning the decoding attribute will have little effect.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding
No preference for the decoding mode; the browser decides what is best for the user. This is the default value, but different browsers have different defaults:
Chromium defaults to "sync". Firefox defaults to "async". Safari defaults to "sync" except in a small number of circumstances.
In reality, the differences between the two values are often difficult to perceive and, where there are differences, there is often a better way.
For images that are inserted into the DOM inside the viewport, "async" can result in flashes of unstyled content, while "sync" can result in small amounts of jank.
For images inserted into the DOM outside of the viewport, modern browsers will usually decode them before they are scrolled into view and there will be no noticeable difference using either value.
I'm leaning towards remove decoding to save the bytes. What do you think?
Some good notes regarding loading on this page:
https://web.dev/articles/browser-level-image-lazy-loading#distance-from-viewport_thresholds
The eager value is simply an instruction to load the image as usual, without delaying the load further if it is off-screen.
eager: Default loading behavior of the browser, which is the same as not including the attribute and means the image is loaded regardless of where it's located on the page. While this is the default, it can be useful to explicitly set this if your tooling automatically adds loading="lazy" if there is no explicit value, or if your linter complains if it is not explicitly set.
Note: Experiments conducted using Chrome on Android suggest that on 4G, 97.5% of below-the-fold images that are lazy-loaded were fully loaded within 10ms of becoming visible. Even on slow 2G networks, 92.6% of below-the-fold images were fully loaded within 10ms. This means browser-level lazy loading offers a stable experience regarding the visibility of elements that are scrolled into view.
I'm leaning towards remove decoding to save the bytes. What do you think?
I kind of disagree. IMO we do in fact by intention want all images to be low priority (hence lazy and async). I understand benchmarking tools (like Lighthouse) penalises lazily-loaded above-the-fold stuff but that's too general. Fundamentally, Lighthouse is trying to prevent layout shift, FOUC, and time to useful content. Which this repo by default solves - with explicit container dimensions, inline-LQIP, and as a best practice don't use images as main content (images supplements main content).
@zerodevx I am building a skeuomorphic design, with most pages having photography as the main content, so I often have different requirements... But I see what you are saying in general for a text-focus website. It sounds like decoding="sync" can potentially cause jank (as opposed to async which can OTOH cause FOUC). The unpic library defaults to async for decoding, but interestingly according to MDN Chromium defaults to sync. Sounds like in most cases the difference is negligible, which is why I wasn't so sure might just as well remove setting it by default (f.ex just to save the bytes).
EDIT: "for loading" -> "for decoding"