Lazy loading of images is important techniques to improve web page performance.
Most Web pages contain multiple images, each of which occupies a relatively large file size. Loading them all at once slows down the page loading process, so lazy loading is effective.
Lazy loading of images is one of the highest priority improvements to speed up the display speed of websites. This article describes two techniques: lazy loading and async decoding of images.
What is lazy loading?
If no measures are taken, all images contained in page will be loaded at once when the web page is initially displayed. Lazy loading is to load only images contained in the first view when the page is initially displayed, and load off-screen images each time when the page is scrolled and needs to be displayed.
If you see a “Defer offscreen images” message when measuring page performance in Page Speed Insights, this is an indication that images are not lazy loading, which is slowing down the page loading speed. Take the following measures to delay loading off-screen (outside the first view area) images.
Two ways to lazy loading
There are following two main ways for lazy loading.
- Add loading=”lazy” to <img> tags
- Use JavaScript
Add loading=”lazy” to <img> tags
By setting the loading
attribute of the <img> tag to lazy
, you can use the browser’s native lazy loading.
<img src="example.jpg" loading="lazy" alt="" width="640" height="320">
Almost all major browsers support loading="lazy"
as of 2024. If loading="lazy"
is used in IE or other non-supporting browsers, the image itself will load correctly, just not lazily.
The loading
attribute can have the following three values.
lazy | Not loaded when the page is initially displayed, but loaded when the page is scrolled and the image is close to viewport |
---|---|
eager | Loaded when the page is initially displayed |
auto | Browser automatically selects lazy or eager depending on user’s data transfer speed |
This loading
attribute can be used not only in <img> tags but also in <iframe> tags. Since <iframe> tags are often heavy with external scripts, etc., lazy loading is recommended.
As a reminder, <img> and <iframe> tags with loading="lazy"
should include the width
and height
attributes. By setting the width
and height
attributes, the browser will preallocate space for elements that will be displayed with lazy loading when the page is initially displayed. This prevents Cumulative Layout Shift (CLS), in which the page layout is shifted due to the insertion of images.
Use JavaScript
This is a method of lazy loading of images using JavaScript. Native lazy loading has the disadvantage that it is not supported by older browsers and can only be used for <img> and <iframe> tags, but these can be solved by using JavaScript.
This chapter explains how to lazily load images using the JavaScript library of lazysizes.
Basic usage of lazysizes
1. Download lazysizes.min.js
from the documentation page or run the installation command (npm install lazysizes --save"
or bower install lazysizes --save
).
2. Include lazysizes in your webpage.
<script src="lazysizes.min.js"></script>
Or:
import 'lazysizes';
3. Add the "lazyload"
class and set the file path to the data-src
attribute. Optionally add an image path to the src
attribute to set the image to be displayed before loading.
<img data-src="image.jpg" class="lazyload" alt="" width="640" height="320">
With the above settings, when the display position of an element approaches due to page scrolling, the lazysizes library will rewrite the value of the src
attribute to the value of the data-src
attribute, and the image will start loading. When lazy loading is complete, the "lazyload"
class is changed to the "lazyloaded"
class.
Other attributes such as data-srcset
and data-sizes
are also supported. See the documentation page for details. In addition, background images can also be lazyloaded by using the unveilhooks plugin.
Comparison of the two methods
There are advantages and disadvantages to both methods, adding loading=”lazy” to <img> tags and using JavaScript.
Adding loading=”lazy” to <img> tags
advantages:
- No additional scripting is required because the browser supports it by default
- Simply add the code to the <img> and <iframe> tags
disadvantages:
- Not supported by IE and older version browsers
- Controlled by browser functionality and cannot be customized
- Can only be used for <img> and <iframe> tags
Using JavaScript
advantages:
- Compatible with IE and older version browsers
- Various options are available to customize the loading method
- Elements that are not <img> or <iframe> tags can also be lazy-loaded
disadvantages:
- Script loading may slow down the initial display speed
- Takes some time to implement
Lazy loading in WordPress
Lazy loading of images has been a standard feature of WordPress since version 5.5.
When you insert images into a WordPress page, the corresponding tags in the output html file will automatically be given decoding="async"
. (decoding=”async” will be explained in the next chapter)
The second and subsequent images in the page content are automatically be given loading="lazy"
. Even if the first image is placed outside the first view, loading="lazy"
is not automatically assigned, only decoding="async"
.
Images to which lazy loading is automatically applied are limited to images inserted by the WordPress editor. It is not automatically applied to tags written directly in the template file (php file). Also, if you write <img> tags in custom HTML in the WordPress editor, loading="lazy"
will be given only if the width
and height
attributes are set.
Async decoding images with decoding=”async“
By writing decoding="async"
in the <img> tag, it is possible to decode images asynchronously.
What is decoding=”async”?
Normally, when a browser displays a page, it blocks page rendering while images are being decoded, causing a delay in the initial display of the page. Using decoding="async"
allows images to be decoded asynchronously in the background, thus speeding up initial page display speed without blocking page rendering.
<img src="example.jpg" decoding="async" alt="" width="640" height="320">
Images with loading="lazy"
are not loaded when the page is initially displayed, but are loaded when it is close to the viewport. In contrast, decoding="async"
means that images are loaded during the initial display of the page, but they are loaded in parallel with the rendering of the page. The difference is that async decoding also reads off-screen images when the page is initially displayed.
As follows, decoding="async"
and loading="lazy"
can be used together. In this case, loading="lazy"
will take precedence and images will not be loaded when the page is initially displayed.
<img src="example.jpg" decoding="async" loading="lazy" alt="" width="640" height="320">
Decoding attribute of <img> tag
The <img> tag’s decoding attribute can be set to the following three values.
async | Decode the image asynchronously and does not block page rendering |
---|---|
sync | Decode the image synchronously (block page rendering while decoding) |
auto | The best decoding mode is automatically selected by browser (default) |
The decoding
attribute is also now available in all major browsers and is compatible with relatively older versions of browsers than the loading attribute.
At first glance, it may seem that there is no advantage to using synchronous decoding with decoding="sync"
. However, asynchronous decoding of images in the first view with decoding="async"
slows down the rendering of the first view because the images are decoded in parallel with the rendering of other contents. Therefore, decoding the images in the first view synchronously and decoding them before rendering of other contents may improves sensory display speed.
The loading
attribute could be set on <img> and <iframe> tags, but the decoding
attribute could only be set on <img> tags.
Which should we use decoding=”async” or loading=”lazy”?
For images outside the first view, it is basically recommended to give priority to lazy loading with loading="lazy"
.
However, in the following situations, it may be better to apply only async decoding with decoding="async"
instead of lazy loading.
- Images included in areas that switch between hidden and displayed, such as modals
- Images displayed by scrolling horizontally
- Initially hidden images in the carousel
Browser will basically load images in areas that are hidden by the display: none;
style. However, if loading="lazy"
is set, the image is not considered to be in the viewport and will not load. When the image switches from hidden to visible in this state, the image starts loading from there, so the display area of the image is blank for a moment while it is loading.
In addition, when loading="lazy"
is used, loading starts at a certain distance before entering the viewport in the case of vertical scrolling. But in the case of horizontal scrolling, loading does not occur until immediately after entering the viewport because of browser’s specifications, and blank space during loading is displayed for a moment.
Conclusion
This post explained the lazy loading and the async decoding of images.
- Lazy loading and async decoding of images can improve initial page display speed
- There are two ways to lazy loading: adding
loading="lazy"
to <img> tags or using JavaScript - Adding
decoding="async"
to <img> tags allows to decode images asynchronously