Lazy loading is a strategy to identify resources as non-blocking (non-critical) and load these only when needed. It's a way to shorten the length of the critical rendering path, which translates into reduced page load times.
Lazy loading can occur on different moments in the application, but it typically happens on some user interactions such as scrolling and navigation.
As the web has evolved, we have come to see huge increases in the number and size of assets sent to users. Between 2011 and 2019, the median resource weight increased from ~100KB to ~400KB for desktop and ~50KB to ~350KB for mobile. While Image size has increased from ~250KB to ~900KB on desktop and ~100KB to ~850KB on mobile.
Lazy loading can be applied to multiple resources and through multiple strategies.
- Entry point splitting: separates code by entry point(s) in the app
- Dynamic splitting: separates code where dynamic import() expressions are used
Script type module
Any script tag with
By default, CSS is treated as a render blocking resource, so the browser won't render any processed content until the CSSOM is constructed. CSS must be thin, delivered as quickly as possible, and the usage media types and queries are advised to unblock rendering.
<link href="style.css" rel="stylesheet" media="all" />
<link href="portrait.css" rel="stylesheet" media="(orientation:portrait)" />
<link href="print.css" rel="stylesheet" media="print" />
It is possible to perform some CSS optimizations to achieve that.
By default, font requests are delayed until the render tree is constructed, which can result in delayed text rendering.
See also: Element Link.
Very often, webpages contain many images that contribute to data-usage and how fast a page can load. Most of those images are off-screen (non-critical), requiring a user interaction, like scrolling, in order to view them.
loading attribute on an
<img> element, or the
loading attribute on an
<iframe>, can be used to instruct the browser to defer loading of images/iframes that are off-screen until the user scrolls near them.
This allows non-critical resources to load only if needed, potentially speeding up initial page loads and reducing network usage.
<img loading="lazy" src="image.jpg" alt="..." />
<iframe loading="lazy" src="video-player.html" title="..."></iframe>
load event fires when the eagerly-loaded content has all been loaded. At that time, it's entirely possible (or even likely) that there may be lazily-loaded images or iframes within the visual viewport that haven't yet loaded.
You can determine if a given image has finished loading by examining the value of its Boolean
Intersection Observer API
Intersection Observers allow the user to know when an observed element enters or exits the browser's viewport.
When browser compatibility is crucial, there are a few options:
- polyfill intersection observer
- fallback to scroll, resize or orientation change event handlers to determine if a specific element is in viewport