23
votes

I know this question was asked many times, but I haven't found answer. So why its recommended to include scripts at the end of body tag for better rendering?

From Udacity course https://www.udacity.com/course/ud884 - rendering starts after DOM and CSSOM are ready. JS is HTML parse blocking and any script starts after CSSOM is ready.

So if we got:

<html>
    <head>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>CRP</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <!-- content -->
        <script src="script.js"></script>
    </body>
</html>

CRP would be:

CSSOM ready > JS execute > DOM ready > Rendering

And if script is at head:

<html>
    <head>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>CRP</title>
        <link rel="stylesheet" href="styles.css">
        <script src="script.js"></script>
    </head>
    <body>
        <!-- content -->
    </body>
</html>

CRP would be the same:

CSSOM ready > JS execute > DOM ready > Rendering

This question is only about "sync" scripts (without async/defer attribute).

6
Rendering is not done at once, but incrementally. If a JS is blocking at the end of the body, the page up to that point will be rendered (if CSSOM is ready).ernesto

6 Answers

24
votes

Scripts, historically, blocked additional resources from being downloaded more quickly. By placing them at the bottom, your style, content, and media could download more quickly giving the perception of improved performance.

Further reading: The async and defer attributes.

4
votes

In my opinion, this is an outdated practice. More recently, the preference is for JavaScript to separate any code that requires the DOM to be present into a "DOMContentLoaded" event listener. This isn't necessarily all logic; lots of code can initialize without access to the complete DOM.

It's true that this causes a small moment when only the script file is being retrieved, and nothing else (for instance, images). This small window can be skipped by adding the async attribute, but even without it I recommend putting script tags in the head so that the browser knows as soon as possible to load them, rather than saving them (and any future JS-initiated requests) for last.

3
votes

It is a best practice to put JavaScript tags just before the closing tag rather than in the section of your HTML.

The reason for this is that HTML loads from top to bottom. The head loads first, then the body, and then everything inside the body. If we put our JavaScript links in the head section, the entire JavaScript file will load before loading any of the HTML, which could cause a few problems.

1.If you have code in your JavaScript that alters HTML as soon as the JavaScript file loads, there won't actually be any HTML elements available for it to affect yet, so it will seem as though the JavaScript code isn't working, and you may get errors. 2.If you have a lot of JavaScript, it can visibly slow the loading of your page because it loads all of the JavaScript before it loads any of the HTML. When you place your JavaScript links at the bottom of your HTML body, it gives the HTML time to load before any of the JavaScript loads, which can prevent errors, and speed up website response time.

One more thing: While it is best to include your Javascript at the end of your HTML , putting your Javascript in the of your HTML doesn't ALWAYS cause errors. When using jQuery, it is common to put all of your code inside a "document ready" function:

$("document").ready(function(){ // your code here });

This function basically says, don't run any of the code inside until the document is ready, or fully loaded. This will prevent any errors, but it can still slow down the loading time of your HTML, which is why it is still best to include the script after all of the HTML.

1
votes

Images placed below the script tag will wait to load until the JS script loads. By placing the script tag at the bottom you load images first, giving the appearance of a faster page load.

1
votes

I think it depends on your website or app. Some web apps are based on JavaScript. Then it does not make sense to include it at the bottom of the page, but load it immediately. If JavaScript just adds some not so important features to some content based page, then better load it at the end. Loading time will almost be the same, but the user will see the important parts earlier (before the page finished loading).

It’s not about a whole site loading faster, but giving a user the impression of some website loading faster.

For example: This is why Ajax based websites can give a much faster impression. The interface is always the same. Just some content parts will alter.

1
votes

This was an extremely useful link. For any given webpage, a document object model is created from the .html. A CSS object model is also created from .css.

We also know that JS files also modify objects. When the browser encounters a tag, the creation of DOM and CSS object models are immediately halted when the script is run because it can edit everything. As a result, if the js file needed to extract information from either of the trees (DOM and CSS object model), it would not have enough information.

Therefore, script srces are generally at the end of the body where most of the trees have already been rendered.