Picture widget is the second most popular in Readymag after Text. Yet, from a viewpoint of bandwidth, images are hogs—they present the average largest project payload. That’s why one of our main optimization challenges is to display high quality images while minimizing their file size.
To meet it, we recently rolled out several updates to the Picture widget. In this piece, Readymag developer Sergey Nechaev describes our journey to deliver optimized images with the proper balance between size and quality. This post shares some technical details that will interest those who want to know how Readymag works under the hood.
Progressive image rendering
We have added a Progressive images toggle to the Project Settings menu. With it switched on, images in a project render gradually for visitors, progressively transforming from blurred previews to full pictures.
Technically, it works like this: when a visitor opens a page, all images in it start with tiny light-weight previews (they are called LQIPs — low quality image placeholders). Once the page is fully loaded, placeholders get replaced with the original quality images. LQIPs don’t actually make images load faster, but they help the user experience by telling page visitors that images are on their way.
We combine this technique with ‘lazy loading’ to make sure that viewers’ browsers only download images when they need them. On a slow connection, visitors get a fully usable page much faster, achieving a significantly better user experience. On a fast connection, the extra download of the LQIPs — or the delay of the high quality ones — does not lead to a substantial hinder.
Our journey to implement LQIPs
Before finding the proper solution, we explored several techniques to implement LQIPs. One of them offers converting the original images into vector graphics. This method did not fit us: image conversion is time consuming and many of the resulting LQIPs looked too ‘rough’ and pixelated even for previews. Another method is using already blurred images, yet such previews are not very beneficial in terms of size.
Another possible approach is to reduce image size. We compressed original images to the radical 40px (by width), saved them in minimal possible resolution, and made blurring browser-side. After forgoing server-side blurring and giving up on the necessity to save images in high quality, the resulting image size turned out to be very compact.
Neat bounds, transparency and rounded corners
There was another problem — we could not apply blurring directly to images in <img> tag — because in this case image boundaries also get blurred. To tackle this, we decided to put such images as background layers and scale them up, so that their boundaries look neat.
For the special case of Background widget, we came up with the following solution: LQIP appears and stays above the widget as long as the main image under it is being rendered. To make the transition visually smooth, we make LQIPs dissolve with a slight transparent effect.
Corners of a Picture widget can be rounded independently, so we had to apply this functionality for the preview LQIP images too. Also, we had to keep in mind that users can set opacity for Picture widgets lower than 100% — in this case, preview images must have the same opacity.
Summing up, progressive image rendering is the best practice for you if your website offers lots of graphics, slideshows and images in the background. In case it has only a couple of images on a page, you just won’t notice the update. Also, it is still not working for SVG and GIFs.
Converting images to WebP
Another major update is that Readymag now converts all images to the WebP — a format created by Google that has superior compression and quality characteristics. The average WebP file size is 25%–34% smaller compared to its older JPEG counterpart, plus it has no pixelation artifacts on color gradient zones — which is typical for jpg. Lossless WebP supports transparency at a cost of just 22% additional bytes. This improvement affects all user projects — even those put together before the update.
We decided to detect support for WebP browser-side. This added one additional check during page load, but freed us from excessive browser-side rendering and helped shorten the html code, as we now don’t have to put all possible image variants in <picture> source and srcset attribute. Yet, srcset elements were left at minimum, because search engines take into account the quality of image retrieval in their ranking algorithms.
Afterwards we worked on the visual quality of images. We had to establish the best image compression settings. It’s quite easy to do with photographs — WebP allows to compress them without any visible artifacts. But in Readymag users often use graphical work, such as logos and interface designs with solid colors and clear bounds. It turned out that for them WebP format with standard settings doesn’t leave visual artifacts but often blurs the bounds. So we took a large pack of real images utilized by Readymag users and found out the best parameters that work for them.
Reworking image delivery mechanics
To introduce conversion to WebP, we had to rework the whole image delivery mechanics. Earlier, Readymag delivered individually-optimized images for each user, depending on their device. It worked like this: after a user uploaded an image in their project, we generated several variations of it, each optimized for screens of different size and resolution, so that the viewer gets the best.
We decided to forgo preliminary images. Instead, we made a service that generates images on-the-fly and caches them for further use. Distributed processing allowed us to do that as quickly as just uploading an image. Once the image is generated and cached, it is retrieved even quicker. This way we got a flexible instrument that allows us to deliver literally individual images for each viewer, especially taking into view Scale layout and animations scaling.
We tested the new format of image delivery on various large projects with traffic starting from 100 MB per view, and the efficiency turned out to be even higher than we expected. On average, the total size of images delivered to a user in the browser decreased by 2.5 times. Not only the conversion to WebP played a role, but also the adaptation of images exactly to widget sizes.