Render blocking defer vs moving script at bottom - javascript

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:
is above true?
are these tools specifically look for 'defer' or 'async' attribute?
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.

Yes, the scripts loaded even at the bottom has to have defere attribute, if it's possible in your site design and requirements
no, those tools looks for the completion of parsing
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.

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.

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?

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

Related

Is it still advised to move JavaScript to the footer of the page? [duplicate]

I always put my script tags at the bottom of the page since it's good practice to load scripts after things like HTML/CSS and text has finished loading. I just found out about the defer attribute which basically does the same thing, that is it waits till the page has finished loading before fetching and executing scripts.
So if using the defer attribute is it necessary to physically place script tags at the bottom of the page vs inside the head tag?
I find it better for readability to keep script tags inside the head section.
<script src="script.js" defer="defer"></script>
or
<script defer="defer">
// do something
</script>
The current best practice? Use deferred scripts in order in the head, unless you need to support older browsers (IE < 10, Opera Mini, etc.) - 97.45% browser usage (ref)
Why? With defer, parsing finishes just like when we put the script at the end of the body tag, but overall the script execution finishes well before, because the script has been downloaded in parallel with the HTML parsing. This scenario will trigger the faster domInteractive event that is used for page loading speed. With async, the order in which your script will execute varies based on how fast the script is fetched, so order can be compromised. Futhermore, async scripts are executed inline and pause the parsing of the HTML.
Best practices have shifted since these answers were written, because support for the defer attribute has grown to 98% globally.
Unless you need to optimize speed for older browsers, you should put the script in the head and mark as defer. This 1) keeps all your script references in one place (more maintainable) and 2) makes the browser aware of the script sooner, which lets it start prioritizing resources earlier.
The performance difference difference should be negligible for most pages, because the browser's pre-loader probably isn't going to start downloading a deferred script until the whole document is parsed anyway. But, it shouldn't hurt, and it leaves more work for the browser, which is generally best.
First of all, the defer attribute is not supported by all browsers (and some that do support it just ignore it). Putting the script at the bottom of the page ensures that all HTML elements above it have been loaded into the DOM before the script executes. An alternative is using the onload method or using jQuery's DOM ready function.
There are different reasons why using defer in a script at the bottom of the HTML makes sense:
Not all browsers support "defer". If you put your script in the HEAD with defer and the browser does not support defer, the script blocks the parallel download of the following elements and also blocks progressive rendering for all content below the script.
If you just place the script at the bottom without defer the browser will continue to show a busy indicator until the page has finished parsing the JavaScript.
In some cases the "script at the bottom without defer" blocks progressive rendering. Tested in Google Chrome 36 and IE11 (see comment below)
It's important to know that every browser handels things like "defer" and also the busy indicators a little bit different.
Best practice should be: Put scripts at the bottom with defer.
Besides the readability aspect I only see advantages by putting scripts at the bottom with defer in comparison to "Script in Head with defer" or "Script at the bottom without defer".
While I agree with you that using 'defer' and placing scripts in header will improve readability, this attribute is still not supported by both desktop and mobile Opera (check this table for details).

Using PageSpeed to eliminate render-blocking JavaScript for jQuery

I have jQuery added at the bottom of the page. However, when I run my site on pagespeed insights (Mobile), I get the error:
Eliminate render-blocking JavaScript and CSS in above-the-fold content
Your page has 2 blocking script resources and 1 blocking CSS
resources.
This causes a delay in rendering your page. None of the
above-the-fold content on your page could be rendered without waiting
for the following resources to load.
Try to defer or asynchronously
load blocking resources, or inline the critical portions of those
resources directly in the HTML.
See: http://learnyourbubble.com and https://developers.google.com/speed/pagespeed/insights/?url=http%3A%2F%2Flearnyourbubble.com&tab=mobile
However, the jQuery is added at the bottom of the page. So it should be below the fold.
How can I remove this error?
It has to do with your font files.
Look at request 19 and 20 in the waterfall. These font files are considered CSS.
Notice how first paint (green vertical line) does not happen until after the font files are loaded?
Then notice the 15 JS files were loaded prrior to the font (CSS) files.
That is what Google is taking about.
Having 16 JS files is beyond excessive.
Try this: Disable JavaScript in your Browser. Notice the only change is in the menu header. Is 16 JS files worth that? I think not.
This article should explain a lot of what's happening: https://varvy.com/pagespeed/critical-render-path.html
In short though the problem is that chrome will need to load your jquery and your foundation javascript to give the initial render of the page. This is why its blocking. Just because the javascript comes after the html, does not mean that the html can be displayed yet. The rendering of the DOM is still going to block while the jquery/foundation is being loaded because chrome thinks they're vital to the page being displayed correctly. Pagespeed complains on these particularly because they're large. To alleviate this problem, there are a few things you can do, some of them detailed in the article above, some of them in here https://developers.google.com/speed/docs/insights/BlockingJS. The easiest way to tell chrome that these scripts are not vital and can be loaded "below the fold" is to add a defer or async tag to them.
I see an error calling foundation() but I will assume that you have removed it to rule it out, but it could be that this same call happens prior to load. Try to always enclose your code like:
(function($) {
// DOM ready
})(jQuery);
Have you tried loading async
Make JavaScript Asynchronous By default JavaScript blocks DOM
construction and thus delays the time to first render. To prevent
JavaScript from blocking the parser we recommend using the HTML async
attribute on external scripts. For example:
<script async src="my.js">
See Parser Blocking vs. Asynchronous JavaScript to learn more about
asynchronous scripts. Note that asynchronous scripts are not
guaranteed to execute in specified order and should not use
document.write. Scripts that depend on execution order or need to
access or modify the DOM or CSSOM of the page may need to be rewritten
to account for these constraints.
Please try with defer tag it's working for me.
<script src="filename.js" defer>

Where is the best place to put JavaScript/Ajax in a document?

Apologies for the dumb sounding question, but I need the experts to clarify.
Out of the three places to put JavaScript, head, $(document).ready, or body, where would the best place be to put some ajax that uses a lot of $GET functions?
For instance I am using a JavaScript function called execute_send() but I am unsure where the best place to put it would be. Below is the error:
Problem at line 67 character 22: 'execute_send' was used before it was defined.
function execute_send() {
Also how does the placement affect the page loading time?
In general, unless for some reason you need it elsewhere, put all of your JS last in the body. The browser won't continue until it's parsed your JS, so it is nice to let the page load first. See http://developer.yahoo.com/performance/rules.html
As an example of when you might actually want to put JS in the head: You might have some A/B testing code that you want to run before the page even renders - in that case, the code should go in the head, because you really do want it to run as soon as possible.
As #Thom Blake said, in general the best place is at the bottom of the <body> (+1 for that) - but I'll expand on that a bit:
The reason for this is that as the browser loads the page, it has to stop loading and parse the JavaScript when it encounters it. So if you have all your scripts in the <head> for instance, there will be a delay in loading all the content in the <body>
Note that this is a delay in loading - separate from the actual execution of the script. Something like $(document).ready() deals with when the script is executed, not with when it is loaded.
Generally, all this matters because you want a web page to feel as responsive as possible, so a best practice list for JavaScript will usually be along these lines:
Place all your scripts at the bottom of the <body> so that the loading of non-JS resources, such as images, is not delayed.
Combine your scripts into a single file, so that the server has to make fewer requests for resources (you'll see this referred to as "minimizing HTTP requests")
Minify you scripts, to reduce their total size, which speeds up loading times
Put any code reliant on the DOM (eg click handlers, HTML manipulation, etc) inside $(document).ready() (or the equivalent method for the JS library in use on the page).
Same subject : whats-pros-and-cons-putting-javascript-in-head-and-putting-just-before-the-body
In the past, i experienced some jquery problems has it was not 'loader' when initialising .. this is why we decided to insert it in the <head>.
In some situations it's not easy to move scripts to the bottom. If, for example, the script uses document.write to insert part of the page's content, it can't be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.
For the rest of javascripts, all before the closing </body> tag.
To explain the 'Why page will load faster' : It wont.
Browsers are single threaded, so it’s understandable that while a script is executing the browser is unable to start other downloads. But there’s no reason that while the script is downloading the browser can’t start downloading other resources. And that’s exactly what newer browsers, including Internet Explorer 8, Safari 4, and Chrome 2, have done.
The difference is visible has your ressources within the <body> tag will load/show sequencialy. When the browser gets to load <script src=...js> the complete file has to be loader before the browser can fetch another ressource. So, it's an illusion, because the browser will load/di more 'visible' content before 'javascripts'.
To visualise the whole thing : firebug > Net (tab)
As stated before, $(document).ready is not a place. (For jQuery, $(document).ready simply ensures that the DOM is fully loaded (ready to manipulate) before any script is executed.) You would place your JavaScript in the <head> or the <body>.
However, putting all of your JavaScript includes and JavaScripts at the bottom of the <body> section is best for loading performance. "Progressive Rendering" and "Parallel Downloading" are blocked for everything below the scripts. If your scripts are the last thing on the page, you're not blocking anything.
This article explains it in more depth.
Example:
<html>
<head>
<!-- MY HEAD CONTENT - LOAD ALL CSS -->
</head>
<body>
<!-- MY HTML CODE -->
<!-- START javascript -->
<script type="text/javascript" src="/ajax/jquery/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="/ajax/jquery/plugins/jquery.random_plugin.js"></script>
<script type="text/javascript" src="/includes/some_other_scripts.js"></script>
<script type="text/javascript" language="JavaScript">
//<![CDATA[
$(document).ready(function(){
// my jQuery/JavaScript code
});
//]]>
</script><!-- END javascript -->
</body>
</html>

If I keep JavaScript at bottom or keep JavaScript in <head> inside document.ready, are both same thing?

If I keep JavaScript code at bottom or keep JavaScript code in <head> inside document.ready, are both same thing?
I'm confused between these two methodologies, http://api.jquery.com/ready/ and http://developer.yahoo.com/performance/rules.html#js_bottom.
Is there any benefit to putting JavaScript code at bottom (just before </body>) even if I keep the code inside.
$(document).ready(function() {
// code here
});
As JavaScript is attached in
<head>
<script type="text/javascript" src="example.js"></script>
</head>
In General, your should put your Javascript files at the bottom of your HTML file.
That is even more important if you're using "classical" <script> tag files. Most browsers (even modern ones) will block the UI thread and therefore the render process of your HTML markup while loading & executing javascript.
That in turn means, if you're loading a decent amount of Javascript at the top of your page, the user will expire a "slow" loading of your page, because he will see your whole markup after all your script has been loaded and executed.
To make this problem even worse, most browsers will not download javascript files in a parallel mode. If you have a something like this:
<script type="javascript" src="/path/file1.js"></script>
<script type="javascript" src="/path/file2.js"></script>
<script type="javascript" src="/path/file3.js"></script>
your browser will
load file1.js
execute file1.js
load file2.js
execute file2.js
load file3.js
execute file3.js
and while doing so, both the UI thread and the rendering process are blocked.
Some browsers like Chrome finally started to load script files in parallel mode which makes that whole problem a little bit less of an issue.
Another way to "workaround" that problem is to use dynamic script tag insertion. Which basically means you only load one javascript file over a <script> tag. This (loader) script then dynamically creates <script> tags and inserts them into your markup. That works asyncronously and is way better (in terms of performance).
They will load all the same in terms of you being able to access the code.
The differences are in the perceived speed of loading of the page. If the javascript is last it will not block any CSS that is trying to be downloaded, which should always be at the top, and will not block any images that need to be downloaded.
Browsers only ask for items as they find them in the HTML but they only have a limited amount of download streams (~10 in modern browsers) so if you doing a lot of requests for images/css and for JS something is going to lose and the perceived speed/ user experience of the page load of your page will take a hit.
They are not the same thing as the ready event is fired when the DOM tree has been built, while scripts at the end of the page may actually execute afterward.
Either way, they're both safe entry points for your app's execution.
The Yahoo! Developer site is saying that if you put JavaScript at the bottom of the page, it won't block loading of other resources by the browser. This will make the page's initial load quicker.
jQuery is specifying a function to load when the entire page has loaded.
If you have a function which executes on page load, it won't matter whether you include it in <head> or at the bottom of the page, it will be executed at the same time.
It's important to consider what the JavaScript is actually doing on your page when deciding where to put it. In most cases, the time it takes to load and run JavaScript makes placing it at the end of the page more logical. However, if the page rendering itself depends on Ajax calls or similar, this might not be the case.
Here's a good read on the subject of document.ready() not being appropriate for all JS.
Position of <script> tag don't involve your script if you use document.ready.
It seems JavaScript is charged faster when placed before </body> but I'm not sure.
Even with the script at the bottom of the HTML document, the DOM may not be fully loaded. All closed elements above the script will typically be ready, a DOM ready event may be necessary in corner cases.

Does it matter where JavaScript is placed on a html page?

I've messing about with html5, I've never really had a good look at JavaScript before.
I'm referencing script file like this (not in the head)
<script src="somthing.js"></script>
However the script only seems to work if it placed below certain elements on the page.
Are there particular situations when it matters where javascript is placed?
Thanks in advance.
If the script isn't waiting for an onload or "ready" event of some sort, it needs to be place after the elements it references (otherwise they won't be there to find). If you're unsure, stick it just before </body>.
In this case it looks like that's exactly what's happening, it's looking for elements that haven't been added to the DOM yet. Placing the script at the bottom of the <body> is one common practice to counter this. Some alternatives are using the window.onload event to run your code, or jQuery's $(document).ready() for example (most major libraries have some equivalent of this).
If your script is acting on an element it needs to either be placed after that element on the page or set up to execute when the page is finished loading. If the script runs before the element has been added to the DOM (which occurs when it is encountered as the browser parses the page), then the script can't find the element upon which you want it to act. Placing the script after the element ensures that the element is available for it to work on. Likewise, forcing it to run after the entire page loads makes sure that all elements are available to the script.
I'd suggest that, in so far as possible, you load your scripts right before the closing </body> tag. I would also look at using a framework, like jQuery, which makes it easy to run your scripts on page load complete and wrap the code inside it's load event.
The best practice according to Yahoo's Performance Rules is to place scripts at the bottom of the page:
The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specification suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won't start any other downloads, even on different hostnames.
In some situations it's not easy to move scripts to the bottom. If, for example, the script uses document.write to insert part of the page's content, it can't be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.
An alternative suggestion that often comes up is to use deferred scripts. The DEFER attribute indicates that the script does not contain document.write, and is a clue to browsers that they can continue rendering. Unfortunately, Firefox doesn't support the DEFER attribute. In Internet Explorer, the script may be deferred, but not as much as desired. If a script can be deferred, it can also be moved to the bottom of the page. That will make your web pages load faster.
Well we'd need to know what was in your script to tell you really, but the short answer is "yes it does matter".
Scripts (essentially) execute when encountered by the browser. A classic blunder is to make a reference to a page element in a script placed earlier in the document than the element it references - when the script is executed the element doesn't exist yet!
It is generally considered appropriate to keep scripts in the head, the solution to the above problem therefore being to attach functional code to onload event handlers.
Bonus round: a much more subtle reason script placement matters is because most browsers will single-thread downloads when they encounter a script (for security reasons and because the script can modify the download requirements for example). This is one of the reasons yahoo recommends placing scripts last in your document, but it's a controversial thing to do for a subtle benefit of perception only.
YES it does.
for example, let's just say your js code is at the top. and it is interpreted before the browser is done setting up a section of the dom tree...in this case the HTML element that you are referencing, if referenced before it is available, will produce an error saying that the element is undefined.
Another reason is the user experience. If the css is at the top, when the html is displayed all looks good, but unless the js is at the bottom, you will have to wait for it to be loaded and be ready for execution before the rest is rendered; therefore, slowing down the rate at which items on the screen are rendered.
I see it a lot. Different strokes for different browsers, but just put the js at the bottom, and css at the top and you avoid having to worry about stuff like this.
It depends on what the script is designed to do. If it is using the document.write() method, then it does matter where it is on the page. If it's trying to reference elements in the DOM, it is best put in the HEAD and have those functions that access DOM elements triggered after the page is loaded.
There are a couple of scenarios where the placement is important.
Assuming you have a function call foo() in your_script.js and you call it before you include your_script.js, than it simply won't work because foo() isn't defined yet.
If the code requires a certain element to be available (for example, a lightbox script) than it is possible that loading the code before your lightbox image elements results in the lightbox not doing anything.
So basically... it depends very much on what scripts you are running. Sometimes it will matter, other times it won't.
Yahoo actually recommends putting your scripts at the bottom. The downloading of a JS file is a blocking action which means nothing else is downloading at that time (such as images/css) By putting your scripts at the bottom the user gets the html/images/css first and actually see the page faster, and your JS downloads after to add interactivity.
Having said that, as the other posts mention, your script has to wait until the dom is ready before actually doing anything to the DOM, otherwise you'll have varied behaviour depending on when the DOM is ready.
Well, here is what I think.
If you need to execute your script, before the HTML starts the render in the clients browser then it will be better to be placed in <head> section.
And if you are executing a JavaScript code which communicates with a element in some way then the script should be placed behind that element, because if the script starts ahead then it can't find its respective element to communicate with. So it is better to placed behind element.
This is not only about where the script is placed in the page, but also when the code in the script is executed.
Script tags normally goes in the head section of the page. However, that means that no elements are loaded when the code loads, and if it executed immediately you can't access any elements. The solution to that is to use the onload event of the page. Example:
<html>
<head>
<title></title>
<script>
function init() {
document.getElementById('message').innerHTML = 'Hello world!';
}
</script>
</head>
<body onload="init();">
<div id="message"></id>
</body>
</html>
Javascript libraries may have other methods of doing something similiar, like the ready event in jQuery.
You can place scripts in the page (although this is not what's recommended by the HTML standard), but if you need to access elements in the page from code that runs immediately, the script has to be loaded after the elements. Example:
<html>
<head>
<title></title>
</head>
<body>
<div id="message"></id>
<script>
document.getElementById('message').innerHTML = 'Hello world!';
</script>
</body>
</html>
Scripts may also be placed late in the page for performance reasons. You can keep that in mind and save it until you actally have any performance problems.
In simple terms : Make sure the element(s) the script accesses is loaded before the script starts executes. Ofcourse if you are unsure put it just before .
Your script likely attempts to operate on the DOM before it is ready. This should not be solved by moving it around, but rather by deferring execution with domready callbacks.
After that is sorted, you should aspire to keep script inside of head. It used to be a common practice to include scripts at the bottom of the page to avoid page- and request-blocking. In HTML5 such performance impacts no longer matter since you can take advantage of async attribute. It allows for the loading of JS files to be initiated without side-effects:
Traditional scripts block the HTML parser, preventing the rest of the page from being rendered until the script has been downloaded and run. Scripts using HTML5 async unblock the rest of the page so it can continue loading while the script is being downloaded. ^

Categories