23
votes

I assume moving script at bottom is same as using defer or async attribute. Since defer and async are not fully legacy browser compliant, I gone with loading script at the bottom of the page.

<html>
<body>
<!-- whole block of html -->
<script type='text/javascript' src='app.js'></script>
</body>
</html>

Before doing this, I ran performance benchmark tools like GTmetrix and Google PageSpeed insight. Both shown 'render blocking' parameter as the main problem. I am bit confused now, as even after I moving these scripts at the bottom to allow content/html to load first; these tools still report render blocking as a main problem.

I did look at the other StackOverflow posts highlighting that though scripts loaded at the bottom has to have 'defer' attribute.

I have several questions:

  1. is above true?
  2. are these tools specifically look for 'defer' or 'async' attribute?
  3. if I have to give a fallback w.r.t defer ( specifically for IE browsers), Do I need to use conditional statements to load non-defered scripts for IE?

Kindly suggest the best approach. Thank you in advance.

4
Not certain what question is? What are you trying to achieve?guest271314
apologise if I am not able descripe it better. I am trying to optimize a HTML page which holds many of the javascripts mostly are external & application libs. ** Since many of the performance tools suggests Javascript is causing render blocking , need to load lazy load after HTML content. In my case , moving javascripts to the bottom still shows render blocking as a main problem. My question is Is my understanding wrong or what do I need to do to resolve render blocking.Robin
Have you tried loading scripts at load event of window?guest271314
Both. Initially it was in HEAD but as per suggestion, I moved it to the bottom (just before end of the body tag). Still results shown sameRobin
By loading scripts within load event of window, meaning not including <script> tags in html; but instead dynamically loading scripts within window load event handler, by dynamically creating and appending <script> elements to document after html has been rendered.guest271314

4 Answers

7
votes
  1. Yes, the scripts loaded even at the bottom has to have defere attribute, if it's possible in your site design and requirements

  2. no, those tools looks for the completion of parsing

  3. depends on the version of IE that you want to support, they will have different recommendations

Now explaining simple script, defer and async a bit, to help you understand the reasons:

Script Simple <script> tag will stop the parsing at that point, until the script download and executes.

Async If you will use async, then the script will not stop parsing for download as it will continue downloading in parallel with the rest of the html content. However, the script will stop the parsing for execution and only then the parsing of html will continue or complete

Defer If you use defer, the script will not halt the parsing of html data for downloading or executing the script. So it's sort of best way to avoid any time addition to the loading time of the web page.

Please note, defer is good for reducing parsing time of html, however not always best or appropriate in every webdesign flow, so be careful when you use it.

1
votes

Instead of async, maybe something like this (thanks @guest271314 for the idea)

<!DOCTYPE html>
<html>
<body>
<!-- whole block of  html -->

<!-- inline scripts can't have async -->
<script type='text/javascript'>
function addScript(url){
document.open();
document.write("<scrip" + "t src = \"" + url + "\"></scr" + "ipt>");//weird quotes to avoid confusing the HTML parser
document.close();
}
//add your app.js last to ensure all libraries are loaded
addScript("jquery.js");
addScript("lodash.js");
addScript("app.js");
</script>
</body>
</html>

Is this what you wanted? You can add the async or defer attributes on the document.write call if you want.

0
votes

According to HTML Spec 1.1 The script block in the html page would block the rendering of the page till the javascript file in the url is downloaded and processed.

Adding Script at the end of the page : allow the browser to continue with the page rendering and hence the user will be able to see the page rendering asap.

[Preferred] Adding defer to the script tag : promises the browser that the script does not contain any document.write or document altering code in it and hence allows it to continue rendering.

As previous thread may be useful to you

Is it necessary to put scripts at the bottom of a page when using the "defer" attribute?

0
votes

Why should the scripts mentioned at last must have defer attribute?

Well, the answer is that by adding defer to last script you are actually reducing the number of critical resources that needs to be loaded before the page is painted which reduces the critical rendering path.

Yes, you are correct by the time you reach the last DOM is parsed but browser has not yet started painting the DOM and hence domContentLoadedEvent is blocked until it finishes the paint and render activity.

By adding async/defer we are telling the browser that the resource is not critical for rendering and it can be loaded and executed after dom content has loaded. This will trigger the domContentLoaded event earlier and the sooner the domContentLoaded event fires, the sooner other application logic can begin executing.

Refer the google link below it clearly demonstrate the concept. https://developers.google.com/web/fundamentals/performance/critical-rendering-path/analyzing-crp