Drag an image or click to select
PNG, JPEG, WebP, GIF, BMP, AVIF
How it works
A placeholder is what takes the place of an image while it downloads. It serves two distinct purposes: reserving the exact space the image will occupy, so the surrounding text does not jump when it appears, and showing something resembling the final content so the wait feels shorter than staring at a grey rectangle.
There are three families of solution. Compact hashes (BlurHash and ThumbHash) condense the image into a text string so short that you can store it in a database column alongside the rest of the record; the browser decodes it and draws the blur. Data URIs (the LQIP thumbnail and the SVG) carry the already-encoded image inside the HTML or the CSS, so they need no JavaScript at all. And the flat colour is the cheapest placeholder of them all: seven characters.
Which one suits you depends on where the HTML comes from. If the images come from a database and you list them by the hundred, the hash is the lightest option per record. If you generate static pages or use a framework that already supports placeholders, the data URI avoids adding decoding code. Every value you see here is computed in your browser: the image is never uploaded to any server.
Examples
blurhash 4 × 3LGHC162?|cKNqSWDjtaghVfjfQfjThe length of a BlurHash depends only on the number of components, not on the size or the content of the image: 4 × 3 is always 28 characters, 3 × 3 is 22 and 5 × 4 is 44.thumbhash3wcKNZpwh3eAiIh3iHiIiHCAB/eHA ThumbHash takes between 17 and 25 bytes, that is 24 to 36 characters in Base64. The exact size depends on the aspect ratio of the image and on whether it has transparency, because the format also encodes the alpha channel.lqip 24 px webpdata:image/webp;base64,UklGRi…A 24 px wide WebP thumbnail usually stays under 1 KB. Being embedded in the HTML it adds no extra request, but it does inflate the document, which is not cached separately.Use cases
- Store a BlurHash or ThumbHash in the images table so a listing or an infinite-scroll feed shows something from the very first moment.
- Fill in the blurDataURL attribute of next/image or the placeholder of NgOptimizedImage when the image is not a static import.
- Avoid layout shift (CLS) in product or article cards by combining the placeholder with the width and height attributes.
- Embed a placeholder in static HTML, an email or a template where you cannot run decoding JavaScript.
- Reuse the same BlurHash on the web and in mobile apps, which have decoders in Swift, Kotlin and Flutter.
- Use the average colour as a container background when the byte budget does not allow even a thumbnail.
Frequently asked questions
BlurHash or ThumbHash?
ThumbHash reproduces the image more faithfully in fewer bytes, preserves transparency and stores the aspect ratio, so you do not even need to know the original size to draw it. BlurHash is older and less accurate, but it has implementations for many more platforms and languages. If you are starting from scratch, ThumbHash; if you already have BlurHash decoders in your stack, there is no reason to migrate.
Does this improve LCP?
Not directly. The placeholder improves the perception of speed and, together with width and height, eliminates layout shift, but the LCP metric is still measured when the real image finishes painting. More than that: if the main image is the LCP element, do not give it loading="lazy" nor defer it behind a placeholder; it is better to mark it with fetchpriority="high" so the browser requests it sooner. Placeholders are for the images that sit outside the first screen.
How many components should a BlurHash use?
Four by three works well for landscape images and three by four for portrait ones. Each extra component adds two characters and a little more detail, but beyond six or seven the difference stops being noticeable to the naked eye, because the result is shown blurred anyway.
Hash or data URI?
The hash takes a few dozen bytes per image and is ideal when there are many on the same page, but it requires client-side code to decode it. The data URI needs nothing at all, though it weighs between ten and fifty times more and travels inside the HTML, which is not cached separately. With a few featured images the data URI is preferable; with long listings, the hash.
Why use the SVG instead of the thumbnail directly?
Because the blur is applied by the browser when it draws the SVG. That lets you start from a much smaller thumbnail without the pixel blocks showing when it is scaled up, and the result looks equally smooth at any size. The SVG also forces the alpha to opaque, so the blur does not make the edges transparent.
Is there a size limit for the placeholder?
It depends on the tool. Angular's NgOptimizedImage logs a console warning when the placeholder data URI exceeds 4000 characters, because beyond that the weight of the HTML starts to outweigh the benefit. That is a good general reference: if your thumbnail passes that value, lower the width or the quality.