When lazyloading images, one question that often arises is, “What should we use as placeholders?” Ideally the placeholder would fill the same space as the real image so that when it is loaded, the layout of the page doesn’t reflow.
One technique (aside from using a generic placeholder) is to use Low Quality Image Placeholders (LQIP) to fill the space. Here, the placeholder is a really, really low-res version of the real image. It will be very small, and since it’s based on the same image as the original, it will give the user an idea of what the image will be.
And although this can, and does, work, one of the drawbacks is the quality of this low-res image. If we compress a rasterized image as much as we can, we could possibly get down to at or under 1K. But in doing so, the image also ends up looking very coarse, with plenty of compression artifacts.
Another approach to get around this is to use an SVG for the placeholder, utilizing a Guassian Blur to smooth out the image. Tobias Baldauf has written about this technique, and has also released a tool called SQIP (SVG-based image placeholders) to help in creating these SVGs. The benefit of using SVGs is we can potentially get the size down to around the same size as the low-res JPEG, but by using blur, we can create a smoother looking image, while still providing the user some visual information about what’s to come.
SQIP is a tool that can take a standard image and generate the SVG-based placeholder. For instance, if we take the original image seen above and send it through, this is what we would get:
In this case, the SVG is right around 700 bytes, smaller than the low-quality JPEG, and smoother too.
Using SQIP
So how do you use SQIP? It’s quite easy. The main (only) requirement is Node.js 6+, and SQIP can be installed via NPM.
Installation
$ npm install -g sqip
CLI use
Once SQIP is installed, you can run it from the command line by specifying the image to convert, as well as other optional arguments.
# Prints an example <img> tag
$ sqip input.jpg
# Saves SVG to a file
$ sqip -o output.svg input.jpg
In addition to the -o
option (filename for output), there are a few other arguments you can supply. Depending on your needs, you may need to play around with them to tweak either the look or the size of output.
# -n Number of primitive SVG shapes (default=8)
# -m Type of primitive shapes to use in generating SVG:
# 0=combo, 1=triangle, 2=rect, 3=ellipse, 4=circle, 5=rotatedrect, 6=beziers, 7=rotatedellipse, 8=polygon (default=0)
# -b Gaussian blur (default=12)
Note: SQIP also has a Node API mode that can be used. Options and examples are in the repo’s README.
Overall, the tool was quite easy to install and use, and I’m thankful that it’s available. Using SVGs for placeholders can be a great option when lazyloading images, and this tool makes that option all the more easier to implement.
Resources
- SQIP, Github repo
- SQIP – Vague Vectors for Performant Previews, by Tobias Baldauf
- Progressive Image Loading using Intersection Observer and SQIP, by Dean Hume