While writing an HTML page, some sites recommend to write the script at the end of the BODY tag instead of writing at the beginning of BODY tag. I read this will increase the performance of page refresh. But how is this helping when the HTML page is rendered only after the DOM parses all the tags?
3 Answers
It's convention to have the dependencies (such as jQuery) within the head tag. However, without loading the DOM into the window there is no way for a script to access it.
Check out the following example:
<!DOCTYPE html>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js
</script>
</head>
<script type="text/javascript">
$('#appleTest').html("Apples are great.");
</script>
<body>
<div id="appleTest">
</div>
</body>
If you were to run this, you would not see 'Apples are great.' in the browser window because the jQuery selection doesn't have anything to select.
If you move the script to underneath the </body>
tag, when the jQuery selector method is called, it can find the div since it has been loaded into the window.

- 271
- 1
- 3
-
Keep in mind that dom manipulation is only one use for js among infinite possible use cases. – ffflabs Aug 15 '14 at 22:12
JavaScript loading isn't part of the DOM, but it's blocking and it will interrupt the loading process until it's done. Even if it's a small script, it's still an extra request and will slow down the whole process.
The truth is browsers only need the DOM structure to start rendering. They don't need the scripts nor do they count for layout purposes. They are just dead weight until they are executed.
Even CSS could be considered unnecessary for the initial rendering process (more or less), but since CSS loading is non-blocking, this isn't an issue.
The performance gain from putting scripts at the bottom can vary, and even if it's a recommended practice, it might not always be harmless. When dealing with CMSes, for example, you might design your theme to load the scripts at the bottom, but you have no control over plugins. This happens a lot with WordPress, for example, and people end up putting script in the head to avoid conflicts with plugins.
Bonus Track
When in comes to tracking scripts, such as mixpanel, inspectlet, even Google Analytics... you might want to detect when a user enters your page and leaves a few seconds later due to slow loading times, an adult advertising block... whatever.
If you put the tracking script and the bottom it might not be able to boot in time to detect that visit, so you won't know you have such an extreme bounce rate. In this case I'd consider putting the script in the head.
If you put resource hints at the beginning, say
<link rel="preconnect" href="https://api.mixpanel.com" />
<link rel="preconnect" href="https://cdn.mxpnl.com/" />
Or
<link rel="prefetch" href="https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js" as="script">
It would mitigate the drawback of loading said scripts in the head.

- 30,738
- 21
- 105
- 131

- 17,166
- 5
- 51
- 77
-
1Can you explain/post a link explaining why "CSS loading is non-blocking"? – dalvarezmartinez1 Mar 27 '17 at 10:18
-
Because stylesheets and fonts do not affect the way in which the DOM will be parsed, they only style it. They can be applied once they are loaded, like in a progressive rendering approach. They are requested once they are found in the DOM tree, but the flow continues without waiting for them to complete whatsoever. – ffflabs Mar 27 '17 at 10:49
It helps because the HTML page isn't rendered only after the DOM is ready: the browser starts rendering the page as it parses the DOM.
This means that you can achieve a faster "load" of the page (even though the DOM isn't ready) by making the browser load the scripts last. The user can see your page, and even interact with it, before those scripts at the end are loaded.
Of course, if your page is all built with scripts, there won't be much for the user to see.

- 806
- 1
- 6
- 12
tag. This method is outdated. Look up `defer`, `async` and `type='module'`.
– Beki May 28 '22 at 12:03