Firefox recently joined Chrome and added support for native lazy-loading images (NLLI). NLLI delays loading images until they’re needed to speed up page load times, and reduce the data needed to display just what’s immediately needed to display a page.
In an earlier article (the above link), I discussed how Safari and Firefox are too lazy (images load only as they become visible) and Chrome is too eager (images load way too early). I explained how lazy loading was implemented in browsers using the IntersectionObserver
API, and how the rootMargin
variable controlled the “eagerness”. In the context of lazy loading images, eagerness is the metric used to discuss when an out-of-view image is loaded.
There isn’t much to do about Chrome’s over-eagerness without abandoning NLLI entirely. It loads images thousands of pixels out of view; potentially wasting device resources and slowing down page load times. However, you can easily make Safari and Firefox a bit more eager so visitors won’t see empty areas as empty areas that should hold images are scrolled into view.
Before I go any further on this topic, I first want to urge you to ensure a better image loading experience for everyone by making good use of progressive JPEG images. Progressive JPEGs can display a partial image early on and fill in higher quality details as it’s being downloaded. This will probably make a bigger difference to more of your visitors than the topic in this article.
Modern image formats don’t support progressive loading. You may be using more modern formats like WebP, but a huge percentage of the web still uses JPEG for most images. Safari doesn’t support WebP so JPEG is still king at least among people using Apple’s browser.
But let me get back on track with lazy loading images. You can enforce a minimum preloading distance by setting up an IntersectionObserver
with the desired rootMargin
eagerness. The rootMargin
specifies an element’s distance from the visible viewport before its downloaded.
I recommend using a rootMargin
of about one–two viewport heights (vh
). That’s the height the visible part of the webpage; or the content part of your browser excluding the chrome. The rootMargin
property only supports pixel values, however. You can copy this value from the window.innerHeight
property.
The following code is a complete implementation that can be used to enhance native lazy-loading images. It won’t override the browser’s default NLLI rootMargin
, but it will help ensure a minimum eagerness.