Posted by ChiptuneIsCool 3/30/2025
My one feedback would be to avoid using attr selectors on the style attribute like [style*="--lqip:"]. Browsers normally lazy compute that string version of the style attribute [1], but if you use a selector like this then on every style recalc it'll force all new inline styles (ex. element.style.foo = bar) to compute the string version.
Instead if you use a separate boolean attribute (or even faster a class) it'll avoid that perf foot gun. So write <div lqip style="--lqip: ..."> and match on that.
[1] https://source.chromium.org/chromium/chromium/src/+/main:thi...
<img src="…" lqip="192900">
I'm also curious to see that they're doing solely grayscale radial gradients over the base color instead of tweaking the base color's `L` value and using that as the radial gradient's center, I'd imagine you'd be doing more math that way in the OKLab colorspace which might give prettier results(?).
Tempted to play around with this myself, it's a really creative idea with a lot of potential. Maybe even try moving the centers (picking from a list of pre-defined options with the two bits stolen from the base color's L channel), to account for varying patterns (person portraits, quadrant-based compositions, etc).
I wonder what other things could be encoded this way. Those generic profile pictures, perhaps? (The ones where your email or account id is hashed to produce some unique geometric pattern.)
Something to note is that Color Theif (Quantize) is using median cut on RGB, it would be interesting to try and extract dominant color in OKLab instead.
I also love the idea of a genetic algorithm to find an ideal match for a given image; it should be possible to simulate radial gradients server & client side with webgpu, but probably overkill for such a simple task.
EDIT: Although it works for me in Chrome, it doesn't seem to work in Safari v16.1.
It's not clear if these placeholders do actually help, especially placeholders with very low quality. In my opinion, they only add visual noise.
I'd focus more on avoiding layout shifts when images load, and serving images in a good format (avif, webp) and size (use `srcset` or `<picture>`).
Well, it depends what you mean by help. It’s very dependent on use case and desired UX. Obviously you can prevent layout shifts without them, you can provide feedback on loading status in other ways, and ensure images don’t slow load time without colored placeholders. But they can provide a pleasant UX for some use cases, when done right. They can be annoying when not done well.
When the CRDT or document sync engine inevitably sync much faster than your blobs you have something to show in that placeholder. If the blob sync fails for some reason, you still have something to show more interesting than your browser’s old broken image logo under your “Sync is slow or broken” warning.
I think placeholders help a bunch in situations like that where your image fetch is a lot more complicated than a URL that you can add in a `src` attribute. It’s also really easy to get into situations where such blob fetching is complex: In cases where you have to respect user and/or tenant privacy and need complex OAuth flows. In cases where you need end-to-end photo encryption. In cases where you need peer-to-peer sync and only P2P sync because you’ve been mandated to reduce touch points and likelihood of accidentally storing photos at rest in middle layers. Situations like images of HIPAA data, PII, PIFI, etc.
On a static site with public (or cookie sessioned) images direct linked by URL, yeah the placeholders don’t do much other than check certain design boxes. There’s lots of other places images (and their metadata) come from, and placeholders are a useful fallback in the worst cases.
Definitely very low resolution, but compared to sites that use a solid color this seems much better. And only requiring one variable is really nice.
The article seems very well thought through. Though for both the algorithm and the benchmark algorithm the half blue / half green image with the lake shows the limitations of this technique. Still pretty good considering how light weight it is.
In fact, LQIP looks better than most of the BlurHash examples in the gallery (https://leanrada.com/notes/css-only-lqip/gallery/); not sure if these were cherry picked or what.
I did deliberately pick some "bad" examples like the blue+green image, and other multicolor images.
I wanted to add an upload function so people could test any image, then i realised I'd have to implement the compression/hashing in the client. Maybe i should!
Here's the transcript and code: https://claude.ai/share/4a562082-b681-4f0c-909c-3c32c34fd050
Great work!
https://www.npmjs.com/package/@squoosh/cli#project-no-longer...
So to clarify, is the GitHub maintained but the npm distribution is not? Or is none of it maintained unless you use the website/app?