When should you add the defer attribute to the script element?
Last week, I wrote how you probably don’t need a DOMContentLoaded event in your JavaScript.
The thing is… if you’re going to wait until the DOM is loaded before running the script, why not just put it in the footer in the first place?
JavaScript in the header can also cause massive bottlenecks and rendering delays, so moving your script to the footer is better for performance, too!
In response, I had a ton of people reply back telling me that adding the defer
attribute on a script
element in the head
will do the same thing and provide better performance gains.
<script defer src="path/to/my/script"></script>
I was a bit confused by this.
How defer
works
From what I understood, defer
told the browser to wait until the DOM content was loaded until before downloading and parsing a script.
Turns out, I was wrong.
Many thanks to the wonderful Katie Sylor-Miller (the creator of Oh Shit, Git!?!) and Aaron Peters for explaining what actually happens to me.
Katie wrote…
With defer the browser can find the script slightly sooner than the preload scanner would, and then it can prioritize/download it in parallel while the DOM is parsing.
This means that the DOM can be completely parsed & domInteractive fires while the JS could still be getting downloaded, rather than waiting till after the JS comes back and gets parsed & executed.
In short: with defer
on a script in the head
, the JavaScript file will download in the background while the rest of the DOM is parsed and rendered. When you get to the bottom of the page, the JS file is already downloaded and ready to run.
So when should you use defer
?
If you have any noncritical JavaScript file, or any code that depends on the DOM being rendered to run, load it in the head
with the defer
attribute.
This will result in the best performance on most browsers.
That is, of course, unless your entire document is less than 14kb minified and gzipped. In that case, you’re better off inlining everything.
Note: you can only use the defer
attribute with external scripts. Do not use it with inlined JavaScript.
What’s browser support like?
The defer
attribute works in all modern browsers, and IE 10 and up.
If you need to support IE9, you probably should use the DOMContentLoaded
event listener with your code, too.
Learn more
Flavio wrote a great article on this topic.
When loading a script on an HTML page, you need to be careful not to harm the loading performance of the page. Depending on where and how you add your scripts to an HTML page will influence the loading time.
And the amazing Steve Griffith put together a super helpful video on the subject, too.