Bring your placeholders to life
Many times when we develop we have to sacrifice the user experience to the performance, for example, when we have to compress images and videos to speed up the loading of a website or to optimize the consumption of mobile data in our app, with this, apart from saving bandwidth (both in client and server) we also achieve that users with poor connection can enjoy a fast and pleasant loading.
One of the most popular solutions to deal with this problem is to use a temporary image that we call “placeholder” while the real image is being downloaded, this offers a good experience to the user since it reserves the holes for the images in the interface without giving the sensation of visual poverty, although it is somewhat monotonous since it is usually only one image, and we don’t want that, our goal is for our users to enjoy a rich and dynamic interface.
Why make a placeholder?
- We speed up the loading of our UI reducing the bandwidth needed for fast loading.
- We avoid shifting the interface down when downloading our real images.
- We make the user focus on what really matters
Blurha.sh⌗
The library Blurha.sh is an open source project that can help us to give life to our placeholders making them dynamic, it is interoperable with multiple languages so they can be generated for example in a server made with Node.js or using a Python script and represent it in our native app made in Kotlin, Swift, Dart or our web with thanks to the JavaScript library.

Generate placeholder with Blurha.sh⌗
To do this the original image (image we want to represent) is passed through the coding function of the library and it returns a short string representing the placeholder. This is something that is usually done on the server side, for example, if we have an API that provides information on movies we can generate the string when registering a new movie or when updating your image to save it in the database as a field.
import 'package:blurhash_dart/blurhash_dart.dart';
import 'package:image/image.dart' as img;
Uint8List fileData = File("img.png").readAsBytesSync();
img.Image image = img.decodeImage(fileData.toList());
final blurHash = encodeBlurHash(
image.getBytes(format: Format.rgba),
image.width,
image.height,
);
print("$blurHash");
As it is a short string we can add it to our responses in the APIs or directly write it in our websites without increasing the load of the calls.
Example of an API response that provides the information of a movie:
{
"original_language": "en",
"original_title": "Fight Club",
"backdrop_path": "/fCayJrkfRaCRCTh8GqN30f8oyQF.jpg",
}
Example of the answer using Blurha.sh:
{
"original_language": "en",
"original_title": "Fight Club",
"backdrop_path": "/fCayJrkfRaCRCTh8GqN30f8oyQF.jpg",
"blurhash": "98HKbX6L/HasJ76s0SxNMKd..aHj6"
}
Use the placeholder generated with Blurha.sh⌗
Once the client receives the string generated by the encoding function we can decode it with the decoding function and represent our placeholder. For example, when we receive the call with the list of films, next to the name of each film we have the field ‘blurhash’ and we can represent them in the interface without having to wait for the real image to be downloaded.
import { decode } from "blurhash";
const pixels = decode("LLPsbX6L{HX90MCIP0SxNMKdO,W.", 32, 32);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const imageData = ctx.createImageData(width, height);
imageData.data.set(pixels);
ctx.putImageData(imageData, 0, 0);
document.body.append(canvas);
Try it yourself⌗
If you liked it and want to try yourself how to generate a placeholder from an image and how it is represented I recommend you to try the generator available in the official website of Blurha.sh, it is really useful when debugging our code and see what parameters are more suitable to our images.

Conclusions⌗
Maintaining a good user experience should be our priority and sometimes we have tools to solve problems in creative and efficient ways.