I'm making a small browser game involving p5.js. My HTML is basically this:
<!-- ... -->
<body>
<script type="text/javascript" src="js/vendor/p5.min.js"></script>
<script type="text/javascript" src="js/vendor/p5.sound.min.js"></script>
<!-- ... -->
<script type="text/javascript" src="js/various/other/scripts.js"></script>
<!-- ... -->
<script type="text/javascript" src="js/sketch.js"></script>
</body>
<!-- ... -->
Most of the time this setup works. However, sometimes (when I first load the page in the browser), I get errors like ReferenceError: p5 is not defined from p5.sound.min.js and ReferenceError: loadSound is not defined from sketch.js. When I refresh the page things work fine again, until I close the browser window.
This looks to me like the scripts are executed out of order, because those are the kinds of errors that would be happening if a script was run without its prerequisites having been run. (sketch.js requires p5.sound.min.js requires p5.js.) The order in which I placed them in the HTML is the order in which I want them to run.
I know about async and defer which affect the way the browser loads and executes JavaScript, and I've tried the latter. However:
adding defer to all <script> tags seems to change nothing.
without async or defer (like above), wouldn't the execution order already be guaranteed and correct?
Is there something else I need to keep in mind?
As always, right after posting the question you find a new trail leading to the solution.
Apparently this has nothing to do with JS execution order, but a bug in Firefox that prevents local files from loading if they end in '.min.js'. I think the workaround for now is to load p5 from a CDN, or change the filename to not include min.
Related
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
I include the jquery external js file with the command:
<script type='text/javascript' src='js/jquery-1.11.0.js' ></script>
I will call it again in the same page a little bit below (this is because I am including this with php classes to make sure it is loaded before going on). So in the page, I will have 2 times the line at different places:
<script type='text/javascript' src='js/jquery-1.11.0.js' ></script>
I want to know if this will create problems in my page and if the script jquery will be loaded 2 times which would be inneficient.
Thanks,
John.
This will create issues for any plugin that is included between those two inclusion.. For example if you have :
<script type='text/javascript' src='js/jquery-1.11.0.js' ></script>
<script type='text/javascript' src='js/jquery-plugin.js' ></script>
<script type='text/javascript' src='js/jquery-1.11.0.js' ></script>
jquery-plugin.js will be overwritten and it will not work.
It will be included twice. There is no need to do it. If you absolutely must write the include tag in two places do it second time conditionally. Code below will include jQuery only if it is not included yet.
<script>
window.jQuery || document.write('<script src="js/jquery-1.11.0.js"><\/script>')
</script>
It should be fine, especially in modern browsers, but it is a little bit strange to do this.
If at any point you load jQuery plugins after the first script tag, these will no longer work because jQuery/$ has been re-initialised.
I can't think of any reason you would need to load this twice, though - are you sure you need to? Your best bet is to put the script tag at the bottom of the page, before closing the <body> tag.
Depending on the library, including it more than once could have undesired effects.
Think of it like this, if you have a script that binds a click event to a button, and you include that script twice, those actions will be ran twice when the button is clicked.
You could write a simple function that you call to load a script and have it keep track of files that have already been loaded. Or, I'm sure you could probably use a pre-existing JS loader such as LabJS and modify it.
Reference: What is the danger in including the same JavaScript library twice
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>
Does the page load faster if i use the javascript before the </body> tag? Example:
<body>
balbllb content
<script type="text/javascript" src="jQuery.js"></script>
<script type="text/javascript">
$(function(){
});
</script>
</body>
The page will still load in the same amount of time, but it might be perceived as loading faster (i.e. you might see DOM element(s) appearing quicker).
If it was me, I would leave your jQuery.js reference in the <head>, and keep your custom stuff before the end of <body>.
I don't know whether it loads faster (I would be surprised) but in this case you no longer need to wrap your code in a $(document).ready as at that moment the document will be ready to be manipulated:
<body>
balbllb content
<script type="text/javascript" src="jQuery.js"></script>
<script type="text/javascript">
// directly manipulate the DOM here
</script>
</body>
Its not about anything happening faster. Its the order in which things happen. Putting scripts at the bottom (right before the closing body tag) makes it so the rest of your content loads before loading the scripts, making it appear that its loading faster.
The total page load time will be the same. But the page will be perceived as loading faster since it will appear to the user faster. The "perception of loading faster" is not a conjecture, it is a fact, proven many times by psychologists.
Remember that if you load your JS libraries at the bottom of the page (as you should), then any dependent scripts must follow the libraries at the bottom.
I was reading a tutorial and the author mentioned to include JavaScript files near the closing body tag (</body>) in HTML.
For what type of functionality should I not declare/define JavaScript include in the head section? It makes sense to me include JavaScript like Google Analytics near the closing body tag. Where should I be careful in defining JavaScript include near the closing body tag?
It will often be argued that for speed purposes you should put script tags right at the end of the document (before the closing body tag). While this will result in the fastest page load, it has some serious downsides.
Firstly, a common idiom with Webpage development is to have a header file, a footer file and your content in the middle. To keep unnecessary JavaScript code to a minimum, you'll often want to put code snippets in individual pages.
If you include jQuery, for example, at the end of the document, your jQuery code snippets (like document ready stuff) must happen after that. That can be awkward from a development point of view.
Secondly, in my experience, because the page load is faster, you can end up noticing certain effects being applied because the page has already loaded by the time they are applied.
For example, if you put a table in a document and right before the body close tag put:
$(function() {
$("tr:nth-child(odd)").addClass("odd");
});
with appropriate styling, that effect being applied will often be visible. Personally I think that makes for a bad user experience potentially. I think often you're better off having the page load slightly slower (by putting scripts at the top) if you don't get disconcerting visual effects.
I generally advocate effective caching strategies so you only have to download JavaScript files when they change, as in Supercharging JavaScript in PHP (but the principles apply to any language, not just PHP) and still putting scripts at the top. It's far more convenient.
By putting them in the <head/> you force the browser to download the files before it can render a page. That causes the perceived load time to slow down.
By placing them in the footer, right before the closing body tag, the browser will not load them until it reaches that point in the parsing of the HTML. That means that the scripts will run later in the page load process but will not block the asset download and rendering process.
Which works best is up to you and how you develop your code.
The Yahoo YSlow tool has advice on this:
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.
Google pagespeed have some nice explanation on how to parallelize downloading of scripts.
Still their advice is to put them in the head of your page.
Script tags should generally be in the head section. The exceptions are when they do significant immediate processing that should be delayed until as late as possible in the page load to avoid interfering with the page coming up, as with Google Analytics, or when the script tag's actual placement is a part of its behavior.
The reason for declaring near the end is that your page can begin drawing before having to wait to fetch the .js.
Ergo, stuff you would want at the end would have no effect on the page rendering, and vice versa.
I like to load a small js file in the head, that handles (1) anything that happens before the page is rendered and (2) the loading of other script files after the page loads, or as needed.
The Place of the <script> Element
The script elements block progressive page downloads.
Browsers download several components at a time, but when they encounter an external script, they stop further downloads until the script file is downloaded, parsed, and executed.
This hurts the overall page time, especially if it happens several times during a page load.
To minimize the blocking effect, you can place the script element toward the end of
the page, right before the closing tag.
This way there will be no other resources for the script to block.
The rest of the page components will be downloaded and already engaging the user.
The worst antipattern is to use separate files in the head of the document:
<!doctype html>
<html>
<head>
<title>My App</title>
<!-- ANTIPATTERN -->
<script src="jquery.js"></script>
<script src="jquery.quickselect.js"></script>
<script src="jquery.lightbox.js"></script>
<script src="myapp.js"></script>
</head>
<body>
...
</body>
</html>
A better option is to combine all the files:
<!doctype html>
<html>
<head>
<title>My App</title>
<script src="all_20100426.js"></script>
</head>
<body>
...
</body>
</html>
And the best option is to put the combined script at the very end of the page:
<!doctype html>
<html>
<head>
<title>My App</title>
</head>
<body>
...
<script src="all_20100426.js"></script>
</body>
“JavaScript Patterns, by Stoyan Stefanov
(O’Reilly). Copyright 2010 Yahoo!, Inc., 9780596806750.”
You should put JavaScript right before </body>. Ideally, your HTML should function without JavaScript, so it should be one of the last things loaded.
Bear in mind that you should use CSS to hide elements and not JavaScript. This avoids seeing elements appear and disappear as the page loads.
You may also come across the following problem...
Problem
In this scenario, I'm going to use PHP as an example.
Your footer.php file may currently look like this:
<script src="jquery.js"></script>
<script src="custom.js"></script>
</body>
</html>
But what happens on the rare occasions you want to add some <script> exclusively for one page? You wouldn't be able to put it after footer.php because you wouldn't be in the <body> tag anymore, but you can't put it before, because then you'll be missing the jquery.js from your code.
Solution
Have a footer-start.php file:
<script src="jquery.js"></script>
<script src="custom.js"></script>
And a footer-end.php file:
</body>
</html>
And have your footer.php be simply:
<?php
require 'footer-start.php';
require 'footer-end.php';
Then, on the rare occasions that you need to use a custom <script> for one page, do this:
<?php require 'footer-start.php'; ?>
<script>...</script>
<?php require 'footer-end.php'; ?>
Doing it this way means you don't have to change all your previous code where footer.php is referenced.
I believe it's better to place script tags just before the closing body tag. Because:
Elements are blocked from rendering if they are below the script.
In Internet Explorer 6 and Internet Explorer 7, resources in the page are blocked from downloading if they are below the script.
It is from this article. Also Yahoo's performance rule 6 is Move scripts to the bottom.
You should do it near </body>. The reason is simple: If you place it into the head area, the files must be loaded before the body area can be. For that time, the user just sees a white screen.
But it depends on your website. I would load frameworks like mootools in the head area, other functions for events or AJAX or something should be loaded near </body>.
The only reason for putting it near the end of the body, AFAIK, is to be able to execute the JavaScript after the web browser has parsed your HTML document. E.g. if your JavaScript deals with "all elements named hello", the browser needs to read the entire document before executing your JavaScript. Makes sense, right?
In e.g. jQuery, you can put your JavaScript anywhere in your document and use:
$(document).ready(function () {
// Your code here
});
...to make sure the entire document has been loaded into the DOM before executing the inner function. Of course, this can be done with normal JavaScript as well, but be careful not to break compatibility with some browsers, because their needs tend to differ a lot.