Lazy Loading is a technique where content is only loaded when it is required. In the case of images, this often means only when the image is on the screen). In this post, I investigate Chrome Canary’s new image Lazy Loading flag, and measure the performance impacts of automatically Lazy Loading images.
According to the HTTP Archive, the Median mobile website is 1271 KB, and has 501 KB images (that means that at the 50th percentile, images make up 40% of the page weight). Further, the LightHouse audits in HTTP Archive finds that that the median site has 92 Kb of images (18% of images KB) that are offscreen. (that’s ~7% of the total tonnage). I recently looked at sites that received a “0” score in the Lazy Load Lighthouse test (60% of all sites completely failed this test), and I found that the median savings for these sites was 520KB. The Lighthouse audit estimated that the median page with a 0 score would load 3.5 seconds faster on a 3G connection!
So how does it work?
I have built a series of pages with very heavy images in order to study the Lazy Loading flag.
- Optimized images delivered over HTTP: https://dougsillars.github.io/indexbg_opt.html
- Optimized images delivered over HTTP2: https://dougsillars.github.io/indexbg_opt_https.html
Let’s look at the HTTP website to see how the page loads with Lazy Loading turned off. Here is a screenshot of the fully loaded page, with each viewport marked by a red line:
Without Lazy Loading
So, how does this page load? Let’s look at a few snapshots I took along the way:
- There is text, but none of the images are in place.
- One green above the fold placeholder image is in place, as is one from final viewport #3.
- The first fill image appears, but not at the top of the page. Text is still shifting.
- 3 of the 4 images at the top have loaded, as have many below the fold. Text is still shifting.
- All images loaded. All text is finally in place.
It is pretty clear that the “top viewport” content is not prioritized, as it only fully appears at the end of page load.
Now, with the Lazy Loading flag enabled, let’s observe the page load:
- Just the text.
- First 2 placeholder images (both in first Viewport)
- All of the background images are in place. Page fully laid out, and 3 of the images in the top viewport are loading.
- Top viewport compete
- 2nd and 3rd viewport complete
- Page complete.
The differences abound. First off, with the Lazy Load flag enabled, the page is fully laid out much earlier in the process. The browser does a HTTP 206 (partial content) request for each image. The first 2KB of each image are requested. Inside the first 2 KB of the image will be metadata with the dimensions and the size in KB of the image. With this information, the browser can create placeholder images and finalize the skeleton of the page. Looking closely at each background image in place, Chrome is also adding the size (in KB) of each image:
Secondly, now that the browser knows the order of the images on the page, the images can be requested in order from top to bottom, loading the most important images (at the top) over images lower on the page.
Is Chrome Lazy Loading Faster?
Today – No. My WebPageTest runs have Lazy Loading being slightly slower than without LazyLoading (The SpeedIndex is slower by about 500ms). However, I expect this to change as the feature becomes more mature.
Currently, the behaviour varies on depending if I test with WebPageTest or with my Mac. I also see differences when requesting images with and http/https.
Desktop Behaviour (Canary 71.0.3558.0)
In Canary desktop, for each image, the first request is of the first 2 KB, and the 2nd request is a full 200, requesting the entire image (this does mean that the first 2 KB of each image are downlaoded twice).
Further, I see that the first four images in my page’s top viewport are downloaded twice (875676). That’s certainly hurting page load time and SpeedIndex.
WebPageTest Behaviour (Canary 71.0.3554.4 )
To enable LazyLoading in WebPageTest use Command line term –enable-features=LazyImageLoading flag in the Chrome tab, (and make sure you are using Canary!).
In the WPT runs, all of the image requests are partial content. Request 1 is of the first 2 KB, and the second request is for the remainder (avoiding the 2KB duplicate download seen on the desktop).
Comparing runs with/without the LazyLoading Flag provides some initial benchmarking of the feature. Currently, SpeedIndex is slower with the LazyLoading flag by about 500ms (with my test website). Here’s one representative comparison.
N.B. the top line is Lazy Loaded, and the bottom is the standard load.
The experimental LazyLoading feature enhances page load in many ways. Requesting the first 2 KB of each image allows the browser to quickly obtain image dimensions, and fully lay out the page with image placeholders. Further, knowing the positioning of each image on the page allows the browser to request images inside the first viewport first, and load subsequent images in order (from top to bottom) on the page.
As it stands today, the LazyLoading feature in Chrome Canary is slightly slower than loading a page regularly, but I expect that the feature will continue to evolve and improve behind the experimental flag, and will reach SpeedIndex values (loading the first viewport) that are faster than loading without browser based LazyLoading.
I am excited to track this feature, as implementing a large performance feature improvement in the browser will help speed up the entire web.