Deferred loading allows us to download or execute elements later than the main elements of the website.
In the same way that preloads are used to ensure that the user downloads or executes necessary elements on the website as quickly as possible, you can do exactly the opposite for elements that do not need to be executed at the start of the page, so that it is viable or efficient for the user.
The loading order of elements on a website directly affects WPO (Web Performance Optimisation), so having control over which elements are loaded on the website, and deferring non-essential elements for the initial user navigation, can significantly help improve the performance of a website.
Deferred loading only makes sense for elements that do not affect the visibility of the page.
To understand deferred loading, we need to recognise that when we make a request on the webpage and proceed to the rendering process, we are downloading and processing all the elements that this webpage contains. The browser does this in an order, both in downloading the content (code, images, videos), and in processing it (executing the code), as the computer has to execute all these actions. Although computers are good at performing these tasks quickly and efficiently, they are not capable of doing everything at once. This is why giving browsers hints about which elements are more of a priority helps to create a better user experience.
JavaScript is the programming language that runs in browsers, making it the ideal programming language to interact with the user, as (except for node.js and others) it is processed in the visitor's browser.
This allows pages to have greater dynamism and functionality. Without JavaScript and its standardised interpretation in browsers, web pages would not function as they do today.
That said, some scripts make sense to be downloaded and executed at the start of the web to fulfil that dynamism, while other scripts need to be executed after the appearance of certain elements to which these scripts refer to function properly.
In addition to being able to alter the order in which JavaScript files or inline/internal scripts are called (by changing their position in the HTML), we have certain attributes and techniques to gain greater control over the execution of these files (when called via external files).
The async and defer attributes only have an effect on scripts with the src attribute, i.e., those that load external elements.
Traditionally, the downloading of a webpage works by beginning to download the elements linearly. Primarily, the HTML, and in the HTML, the elements are set to be downloaded through tags. These elements, in turn, can download other elements and delay execution (for example, CSS can call more CSS files via @import, and JavaScript does the same). So when a script is encountered, the HTML download stops, the script begins downloading, it is executed, and after its execution, the HTML download resumes where it left off. With the async and defer attributes, we can make this process work differently.
Also known as asynchronous loading, async allows the JavaScript element to be downloaded in parallel with the HTML parsing. Once the script is fully downloaded, the HTML download will stop as with a traditional script, and once execution is completed, the HTML download will resume.
<script async src="script.js"></script>
Special care must be taken when using ASYNC because the time it takes to download may vary between users, so the script with the async attribute will execute in a different place in the DOM for different users. Therefore, it is essential to ensure that this script does not need to be executed before or after an element located after this script in the original HTML, as this could cause errors. It should only be used if it has no dependencies on other scripts.
This would be the most definitive form of deferred loading. The defer attribute allows the JavaScript file to be downloaded in parallel, just like async, but it will always be executed at the end of the HTML download and execution, thus creating an effect quite similar to a preload and the script will be executed at the end of the entire page.
If we use the defer attribute, we must ensure that the script does not require execution before any specific element.
<script defer src="script.js"></script>
A graphical example of how each of these downloads would work:
Delayed loading consists of programming with JavaScript itself so that something does not happen until a certain time has passed.
This is functional, for example, for analytics scripts. You might lose effectiveness in analysing bounce rates, but if this analytics tool is not used to analyse bounce rates but other statistics, it is quite functional. For example, for Clarity, Hotjar, or Metrika, if what you want to analyse are heatmaps and user recordings.
Example:
setTimeout(function(){
(function(c,l,a,r,i,t,y){c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", "xxxxxxxxxxx");
}, 1000); // Choose the time without negatively impacting your statistics.
Lazy loading involves making elements that the user is not currently viewing not be downloaded until they reach the part where those elements are needed, or until the website is fully loaded (optional).
Due to the use of this practice, HTML5 saw significant progress and included an attribute that directly creates this effect. The attribute is loading, and the value to activate lazy loading is lazy.
This attribute can be used in IMG tags and Iframe.
<img src="image.jpg" loading="lazy" />
<iframe src="https://example.com/iframe" loading="lazy"></iframe>
Although not all browsers support this attribute, especially in the iframe tag, it does not have a negative impact other than not performing lazy loading in browsers where it is not interpreted.
Lazy loading via JavaScript performs the same function and was the most popular option before the native option existed. However, it remains a viable option for "non-standard elements" that require lazy loading.
It is best to see a practical case where this practice is useful and necessary today.
We often encounter elements such as images that are still impacting the download but are being loaded through a CSS background. In this case, the native function does not work, as it is not the image that is loaded through a src in an img tag.
So, we could make that div have a "data-src" attribute, for example, which is where the image URL is added. This way, we get the image URL we want (if they are dynamic images that depend on database calls, otherwise, it is much simpler).
Then we could have a div like this:
<div class="posts-picture" data-src="<?php echo "$image" ;?>">
Now we need the script (using vanilla JS) that should load after this element. (Remember, you could do it via an external JS file with a defer attribute).
document.addEventListener("DOMContentLoaded", function() {
// Select all images with lazy loading
var lazyImages = document.querySelectorAll('.posts-picture .other-classes-you-want');
// Function to load the images
var lazyLoad = function() {
lazyImages.forEach(function(image) {
if (image.getAttribute('data-src')) {
// Set the background image using the data-src attribute
image.style.backgroundImage = 'url(' + image.getAttribute('data-src') + ')';
// Remove the data-src attribute to avoid further loading
image.removeAttribute('data-src');
}
});
};
// Options for the IntersectionObserver
var options = {
rootMargin: '0px',
threshold: 0.1
};
// Create the IntersectionObserver with a callback function
var observer = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
// When the image is visible in the viewport, load the lazy image
lazyLoad();
// Stop observing the image to avoid multiple loads
observer.unobserve(entry.target);
}
});
}, options);
// Observe all lazy images
lazyImages.forEach(function(image) {
observer.observe(image);
});
});
In this way, those background images would only be downloaded in the browser after the script is executed when the user reaches the part where the elements with the selected classes become visible.
It is not as efficient as the native attribute, but it is quite effective where the native attribute does not reach.
Shopify previously used lazysizes, which was quite popular and has a lot of documentation online, but Shopify discontinued it. Therefore, it is not recommended to use it.
There are many plugins and tools that use lazysizes, which could cause security and maintenance issues. If you want to implement lazy loading automatically, you can implement it via image_tag in liquid.
Although it can be done natively and programmed to implement better. Since version 5.4 of WordPress, although I have still seen it has deficiencies in loading some lazy images visible at first, its implementation is improving with each update.
So care must be taken, on the contrary, and apply loading="eager" to those images or iframes that load at the beginning of the website to avoid a poor user experience. This will make it perform a default loading, that is, without "lazy loading".
<img src="image.jpg" loading="eager" />
Load on interaction (link to a step-by-step example of how to do an onclick) involves making a resource not load or execute unless the user performs an action where they want to activate it.
This happens with embedded YouTube videos or with analytics tools (on the first load) when the Cookies policy is properly configured (according to European standards).
This way, the file will not be downloaded until the user hovers, clicks, or the designated and programmed action occurs. This lightens the load of resources that the user may not use.
CSS is vital for making a website visually attractive and functional. Generally, it is recommended to place CSS as early as possible in the Head, and if possible, before any script, so that the page is rendered as quickly as possible and looks as it should.
However, not all CSS resources need to be loaded when viewing a page. For example, when there are hover effects on an element, or certain transitions on a website, they are not necessary visual supports for the proper display of the page, but simply resources that enhance the experience, but do not need to be loaded in the initial page requests. These CSS parts could be called perfectly from the footer.
Similarly, visual resources such as the navigation bar and elements that appear "Above the fold" (in the viewport as soon as you access a page) should be called before other CSS elements that will not be viewed as quickly. For example, the classes of elements positioned in the footer of a website.
It could be said that placing these non-essential CSS elements in the Footer would be "a kind of deferred loading". After all, CSS significantly affects the rendering of a page, so there may be elements that take priority over the style of certain elements.
I currently offer advanced SEO training in Spanish. Would you like me to create an English version? Let me know!
Tell me you're interestedIf you liked this post, you can always show your appreciation by liking this LinkedIn post about this same article.