My personal blog over at heipei.net is a little different to this one. Rather than text- and code-heavy content, it is mostly photos with some text in between. I’ve already spent countless hours optimizing every performance aspect of the site, sometimes including brand-new directives such as preconnect hints. But at some point there is no way around the fact that the blog contains a lot of high-fidelity images from Flickr, a site that is known to not compress it’s photos aggresively, which is a good thing for photographers.
So the only way to improve the perceived performance is to load photos only when they are needed, i.e. when they’re about to become visible. This is known as lazy-loading and can be accomplished quite easily using a variety of JavaScript libraries. I combined lazy-loading with a simple mechanism for responsivesness to make it work better for my use case. This will certainly not fit all applications, but should give you an idea just how easy it is do implement something like this yourself.
Flickr used to have a more generic Share dialog. Unfortunately, nowadays they only offer an intrusive JavaScript-based snippet for embedding photos in your website. It works well enough, but neither do I need it nor do I want additional JavaScript on my site. The way I go about this is to copy the Embed URL and transform it in my paste-buffer:
Transformed via:
which gives me:
This is the format I use in my Jekyll blog-posts. I get rid of width
and height
as well since I might always change
the dimensions of this blog in the future.
For lazy-loading, I used the echo.js library, though I suppose that any similar
library would do. The way that echo.js works is by not setting the src
attribute of the image but rather setting the
URL of the image in the data-echo
attribute. Then, at runtime, the echo.js library can set the src
attribute just in
time when the viewer is about to scroll to the image.
I’ve used a variety of these libraries over the lifetime of my blog, so whenever I switched to a new one I would have to
go back and edit the image tags of all old post to accomodate the new way the library would do lazy loading. Quite
painful. Since I’m using Jekyll now I’ve simply included a preprocessing step for image tags. In _layouts/post.html
I’m using
Which will transform regular image tags like
into this HTML for the output:
The beauty of using the Jekyll processing step is that I can turn echo.js of at any moment if I no longer want to use it.
Lazy loading already works wonders for page-load speed on any device. The other big issue that I faced was the enormous size of flickr photos. For landscape-photos, I include the large size, which is 1024px wide. For my latest post, just the first photo is a whopping 362kB of incompressible JPG data. The next smaller size, called medium at 800px wide, is 250kB in size, already a big improvement. For small devices (say 480px wide), I can get away with the medium size at 500px wide at about 100kB, a three-fold improvement.
Flickr offers photos in a variety of pre-defined sizes, indicated by the filename suffix. This makes it straightforward to replace images with a simple substitute. I thought about it a little bit, and came up with this simple workflow:
data-echo
attributeComparing a desktop load and a simulated Nexus 5x load of my most recent blog post:
Desktop load
Mobile load (Nexus 5x)
This is the simple Coffeescript-code to achieve just that
This is still a very crude and not quite generic way to resize flickr photos. I imagine this could be done in a more generic fashion, e.g. as a small JavaScript library that can be included into pages to make any included flickr photos more responsive. But, as you can tell from the code above, the time spent searching for a library which does exactly what you need and does not interfere with the rest of your page usually takes longer than simply writing a few lines of JavaScript or CoffeeScript yourself.
If you have ideas on how to improve upon these techniques, let me know via the comments! I’ll upload the Jekyll source of my main blog to GitHub soon, once I’ve cleaned up the code base a little bit.
Comments