RSS
Search

Native image lazy loading has landed in Chrome, maybe don't use it

Native lazy loading for iframes and images landed in Chrome 76, but don't go ripping out your existing lazy loading strategy just yet.

Lazy Loading Images

Web browsers are complex pieces of software, but still treat images relatively naïvely. See, for example, a section of this waterfall where almost 100 images are loaded immediately on first-view:

Waterfall section showing bandwidth consumed by off-screen images delays javascript resources
Waterfall section showing bandwidth consumed by off-screen images

On this client's site all but four of the images downloading in the screenshot (shown in purple) are off-screen. Those images are totally invisble to the user on desktop and mobile, but compete for bandwidth with critical resources like the application JavaScript (yellow). Making matters even worse - browsers will download images in the order that they appear in the HTML document, and this client has a dozen images in their hero navigation menu which is at the very top of the HTML. Again, these are invisible to the user at page load time, but are loaded before the critical hero images.

Lazy loading is an approach to provide a hint (or trick) the browser so that visible images are prioritised higher than offscreen images. There have been multiple libraries which offer this functionality, see lazysizes.js. The general premise is to remove the src attribute, so the browser does not download anything, then add a src later in the page load which will trigger an immediate download by the browser.

Native lazy loading

As of Chrome 76, released Jul 30 2019, web developers can provide a native hint to the browser that an image can be loaded lazily by adding the attribute loading='lazy' to the img element. See more details on the web.dev blog.

Not ready for prime time

This release has received a lot of attention on developer twitter. Multiple tweets show developers removing their 'legacy' lazy loading approaches and replacing them with the simple loading attribute. While adding the loading attribute is a positive step for sites without any prior lazy loading strategy, moving to it as a replacement will almost definitely degrade overall user experience.

The browser support for loading is less than 1% at the time of writing. This number will climb to about 60% globally once the Chrome 76 rollout to mobile and desktop completes. There will be a further ~1% increase in global support when MS Edge updates.

CanIUse.com for native lazy loading on Aug 13 2019 shows 0.15% support globally
CanIUse.com for native lazy loading on Aug 13 2019 (see latest stats)

Safari is notably lacking from the support list. This is not a surprise, as Apple are notoriously slow to update their browser (and are opaque about roadmap), but is a serious concern for most western websites. If your Safari traffic is greater than 50%, like many of my publishing and fashion clients, moving to the loading attribute will result in a net-negative performance change.

The future of lazy loading

The initial implementation of loading in Chrome is not complete. There are issues with printing and exporting (looks to be resolved in v77) and the options eager and auto are currently identical in functionality. In the future, the plan is for auto (the default behaviour if no loading attribute is supplied) to be determined by the user's network conditions or data saver preference (or is it Lite Pages?). This means that the performance of your pages should be improved for users with the worst experience, but outside of your control (unless you add the attribute and set it to eager or lazy).

If you're not currently collecting the data saver preference in your analytics tool of choice, this could result in some confusing metrics!

Conclusions

Supporting lazy loading hints natively in the browser is a huge step forward for web performance. Using the loading attribute as the sole approach for lazy loading will be the recommendation once WebKit and Safari implement support. For now, though, it should only be used as an enhancement and not as a replacement for existing strategies.

A great worked example was published by the BBC, where they added the loading attribute to images in an internal app, presumably a very high proportion of Chrome Desktop traffic. The results were a 50% reduction in load time and 40 fewer requests per pageview. This is a great use case for native lazy loading.

In the interests of full disclosure, I use the loading attribute on this site (try inspecting the images in this post). I had no lazy loading strategy beforehand, so it is a progressive enhancement. Over 70% of the traffic to this site is from Chrome, so this should be a reasonable improvement. I had previously experimented with a home-brewed lazy loading technique, but the JavaScript overhead was significant enough to negate most performance benefits.