Dec 12, 2021 by Thibault Debatty | 8929 views
In this blog post, we explain and illustrate the effect of the defer
and async
attributes.
Here is an example of a simple page, that contains external javascript:
<!doctype html>
<html>
<head>
<script>
console.log('Start ...');
</script>
<script src="script1.js"></script>
</head>
<body>
<script src="script2.js"></script>
<script src="script3.js"></script>
<h1>Javascript</h1>
<script>
console.log('Inline JS');
</script>
</body>
</html>
When no attribute is mentioned (like in the example above):
This is a very conservative behavior: the rendering of the page is quite slow, but there is no surprise. If you use <script src='...'>
to load external libraries (like JQuery or others), you can use them in you inline scripts without afterthoughts…
The defer
allows a first level of optimization:
<!doctype html>
<html>
<head>
<script>
console.log('Start ...');
</script>
<script src="script1.js" defer></script>
</head>
<body>
<script src="script2.js" defer></script>
<script src="script3.js" defer></script>
<h1>Javascript Defer</h1>
<script>
console.log('Inline JS');
</script>
</body>
</html>
With defer:
In our example, this time the title appears immediately on the screen…
With the async
attribute:
In our example the result is the same as for the defer
example:
However, in some cases the external scripts may execute in a different order, for example if a script is smaller (and faster to download) than others, or if a script is already available in cache…
Now, in some cases we would like to use the defer
or async
attributes (for performance), but execute inline javascript after external scripts have been executed. For example, if we load libraries (like JQuery) from external scripts, and want to use it in our inline javascript. For this purpose we can use the DOMContentLoaded
event listener:
<script>
window.addEventListener('DOMContentLoaded', function() {
(function($) {
# do something...
})(jQuery);
});
</script>
In our example:
<!doctype html>
<html>
<head>
<script>
console.log('Start ...');
</script>
<script src="script1.js" defer></script>
</head>
<body>
<script src="script2.js" defer></script>
<script src="script3.js" defer></script>
<h1>Javascript DOMContentLoaded</h1>
<script>
window.addEventListener('DOMContentLoaded', function() {
console.log('Inline JS');
});
</script>
</body>
</html>
This time the title is displayed immediately, but our inline code is executed after the external scripts:
This blog post is licensed under CC BY-SA 4.0