I'm making some simple changes using javascript to HTML elements already existant when the page is served (such as changing background images of div elements, adding IDs etc). This of course works fine in every browser apart from IE8 where the change doesn't appear to be reflected in the DOM so when I parse the dom after the JS has run it cant find the elements I'm looking for. The page is built up of 2 javascript files in the header, 1 is an external third party script which I do not have control over but which is the one adding the ids and background images. The second is mine which is called after the first and is parsing the document looking for the specific elements with the new IDs. Both are external scripts and are not inline in the HTML source.
From what I can tell its either:
a race condition, 2 external Javascripts are running 1 is changing the buttons and adding the ids and the other is parsing the dom looking for specific elements and as they're running at the same time the second never finds the elements
IE8 does not properly refresh the DOM after changes have been made
My JS is called after the first JS in the head so you would assume that the blocking would not cause the race condition and the elements would be available before my JS runs
Things I've tried:
I've tried adding a class to the body to force a refresh of the DOM before my code runs
I've used IE8 developer tools and the ids and elements are not present, but if I refresh a few times they magically appear (the page has already fully loaded at the this point and I can interact with it fully)
Any ideas?
Thanks!
One thing to keep in mind is that when you are creating multiple <script> tags, you are not guaranteed of the order in which they load, and depending on how they are build - they will generally begin processing as soon as they are loaded.
So, if you are including one local file and one file to a CDN, such as:
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
</script>
<script type="text/javascript" src="/js/my_script.js"></script>
You have to take into account that the CDN file is often far faster for delivery than your hosted file. In the above case, this may be a good thing - because jQuery being loaded on the page before your script is probably ideal - but if you are loading a different 3rd party script, which may rely on certain elements being present in the DOM that your script is responsible for creating, your script may not create them in time.
Imagine this scenario:
<script type="text/javascript" src="https://someurl/somelib.js">
// This script parses the DOM and applies alterations to certain items
</script>
<script type="text/javascript" src="/js/my_script.js">
// This script creates the DOM elements the other script is supposed to alter
</script>
Your page will only work if the local file, /js/my_script.js, loads first - which is unlikely because the other file is being served from a dedicated CDN.
This is even worse when both files are served locally, such as:
<script type="text/javascript" src="/js/my_relied_upon_script.js"></script>
<script type="text/javascript" src="/js/my_reliant_script.js"></script>
In this case, it all depends on how your local web server happens to handle the HTTP requests in order to determine what happens in what order.
So - on to the solution:
1) Make your scripts all wait for the document's onready event to fire. Because this event only occurs once the document is fully loaded (including any other HTTP requests necessary to fully load its elements, such as scripts, images, etc.) - you can be guaranteed that the scripts will at least wait until the full DOM is loaded.
2) Make subordinate scripts wait for trigger events.
With jQuery, an example might be something like the following:
// Script #1
$(document).bind('ready', function () {
$('#NeedsBackground').css({ background: 'url(/gfx/bg.png)' });
var $wrapper = $('<div />').addClass('wrapper');
$('#NeedsWrapper').wrap($wrapper);
// Here's the magic that enforces loading.
$(document).trigger('Script1Finished');
});
// Script #2
$(document).bind('Script1Finished', function () {
$('.wrapper').css({ border: '1px solid #000' });
});
Now - bear in mind that the above transformations are fairly terrible, and not something you'd want to do (such as inlining CSS and such, generally) - but they give an example. Because Script #2 requires that the .wrapper elements exist before running, you need to ensure that it happens AFTER Script #1 occurs.
In this case, we're accomplishing that by triggering a custom event on the document, which we can then respond to - and we are only firing that event after the DOM has been put in the proper state.
Related
This question is just to clear some things up. Some things like this have been asked before, and this rounds them all up into one question - where should JavaScript go in the HTML document, or, more importantly, does it matter? So, one of the things I'm asking is, does
<head>
<script type="text/javascript">
alert("Hello world!");
</script>
</head>
at all differ (in terms of functionality) from
<body>
<!-- Code goes here -->
<script type="text/javascript">
alert("Hello world!");
</script>
</body>
More importantly, I want to focus on JS that modifies or uses elements from the DOM in any way. So I know that if you put something like document.getElementById("test").innerHTML = "Hello world!" before <element id="test"></element> in your body, then it won't work since the body is loaded from top to bottom, making the JS load first, which will then proceed to try to manipulate an element that doesn't exist yet. So it should, just like the above, either go in the <head> or just before the </body> tag. The question is, aside from organisation and sorting, does it matter which one of these is chosen, and if so, in what way?
Of course, there is also a third method - the jQuery way:
$(document).ready(function(){ /*Code goes here*/ });
That way, it doesn't matter where in the body you place the code, since it will only be executed when everything has loaded. The question here is, is it worth importing a huge JS library just to use a method the need for which could be replaced with an accurate placing of your scripts? I'd just like to clear things up a little here, if you would like to answer, go ahead! Summary: where should different kinds of scripts go - head or body, and/or does it matter? Is jQuery worth it just for the ready event?
Most recommended method is to put it before </body> tag. Yahoo performance article also suggests that other than YSlow and Page Speed addons by Yahoo and Google respectively.
Quoting from Yahoo article linked above:
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.
When you put scripts in <head> tag, the browsers goes for them thereby keeping other stuff on hold until scripts are loaded which users will perceive like slow loading of the page. This is why you should put scripts at the bottom.
As for:
$(document).ready(function(){/*Code goes here*/});
It is fired when DOM is available and ready to be manipulated. If you put your code at the end, you won't necessarily need this but usually this is needed because you want to do something as soon as DOM is available for use.
Although common practice, putting script tags in the head is not usually a good idea, as it holds up the rendering of your page until those scripts have been downloaded and processed (barring your use of async or defer and the browser supporting them).
The usual recommendation is to put script tags at the very end of the body tag, e.g., just before </body>. That way, all of the DOM elements above the script will be accessible (see links below). One caveat on that is that there can be a brief moment when your page has been at least partially-rendered but your scripts not processed (yet), and if the user starts interacting with the page, they may do something to raise an event that your script hasn't had time to hook yet. So you need to be aware of that. This is one reason for progressive enhancement, which is the idea that the page will work without JavaScript, but work better with it. If you're doing a page/app that just won't work without JavaScript at all, you might include some inline script at the top of the body tag (e.g., <script>minimal code here</script>) that hooks any bubbling events on document.body and either queues them for action when your script is loaded, or just asks the user to wait.
Using features like jQuery's ready is fine, but not really necessary outside of libraries (e.g., if you're in control of where the script tags will be, you don't usually need to use it; but if you're writing a jQuery plug-in that needs to do something on load [which is relatively rare, normally they just wait to be called], you usually do).
More reading:
YUI Best Practices for Speeding Up your Website
Google on when the DOM will be ready
It is possible to download javascripts in parallel by doing something like this:
(function () {
var ele = document.createElement('script');
ele.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js";
ele.id = "JQuery";
ele.onload = function () {
//code to be executed when the document has been loaded
};
document.getElementsByTagName('head')[0].appendChild(ele);
})();
In the example it downloads minified JQuery v1.7.2 from Google, this is a good way to download JQuery since downloading it from Google is like using a CDN and if the user has been on a page that used the same file it might be cached and therefor doesn't need to be downloaded
There is a really good Google tech talk about this here http://www.youtube.com/watch?v=52gL93S3usU&feature=plcp
I mean : I know the JS is cached only if it come from a .js file. Also, 90% of my functions must be rendered when the page (html) is loaded (rendered), so it is better put JS before closing the body tag. (this prevent also to use document .ready(); and the loading of the page itself will be more faster).
So, which is the advantage on putting JS in the <head></head>? Expect the "order" of the code, which I don't mind so much to be honest...
Placing a <script src> tag inside the <head> section makes sense – semantically. It does block the browser from rendering anything until the script is loaded but assures that an object (e.g. jQuery) is available in the rest of your code (in the body for example).
A common practice is to load a light weight script loading library (HeadJs, LABjs, etc) inside the head section, then load the heavy stuff lazily and/or on-demand.
Having said that, HTML5 introduced the async attribute for script tags and re-introduced the defer attribute (docs). So you now have a very good and valid reason for putting <script src> tags inside head sections because:
it makes sense
the script still loads after the page has finished loading
The <script> tag causes two problems:
Everything below the script won't render until the script is loaded.
All components below the script don't start downloading until the script is done.
Putting it into the <head> only really makes sense if you need to execute some JavaScript before anything gets rendered.
So placing it as low as possible in the page would result in a better user experience.
It's slightly more semantic to put it in the header, but it doesn't generally have any advantages. Sometimes it is necessary - for example, loading fonts using JavaScript (using stuff like Google Webfonts) has to be done in the header, or the page will render with the wrong font and then change, which won't look good to the user.
The important thing about the elements in the <head> section are that they are loaded, before the <body> starts to load.
This is a very efficient feature, which are used a lot (IMO).
Loading of libraries, scripts, that have to run before the DOM has loaded have to done in <head> section.
I will give you a scenario
Imagine, You needed to calculate the 30% size of the screen's total size and assign it to the element inside.
It would be foolish and wait for the element to load big, then run the script to load resize it again.
If you have JS code which is intended to run as part of loading/building the page, where in the HTML should this go? For instance modifying a <div> or adding some links.
Should this be put in the <body>, interspersed with HTML? Or should it be between the <head> and <body> elements? What order do things happen in - the order they are in the page or does HTML all happen before (non-<head>) JS is run?
If you have JS code which is intended to run as part of loading/building the page, where in the HTML should this go?
Just before the closing </body> tag is emerging as the best practice barring a specific requirement for it to be elsewhere (which there can sometimes be). It's the recommendation of the YUI folks, for instance, but it's not just them.
What order do things happen in - the order they are in the page or does HTML all happen before (non-) JS is run?
When a script tag is encountered, unless you use the defer or async attribute (and the browser supports them), all HTML parsing comes to a screeching halt and the script is downloaded and handed to the JavaScript interpreter. When the JavaScript interpreter finishes processing the script, the HTML parser can continue. It has to do this because the JavaScript can insert tokens into the HTML stream via document.write. This is also why you can load a script file and then load a second script file that relies on the first, and know that they'll get loaded in the right order. It's also why you can't access elements that are further down in the HTML stream from a script higher up in it unless you defer your code somehow (window.onload or the "DOM loaded" events many libraries support, such as jQuery's ready or Prototype's dom:loaded).
An upshot of this is that the typical practice of putting script tags in the head actually slows down the apparent load time of the page, unless those script tags need to be there for some reason. Hence the recommendation to put them just before the closing </body> tag.
There's a "gotcha" you have to watch for, though: If you have parts of the page that you want to respond to with JavaScript if the user has it enabled, loading your script at the very end leaves a brief but real race condition lying around: The user can interact with the page while your script is being downloaded. There are a variety of ways of handling that. My favorite is to detect whether JavaScript is enabled with inline script (not a separate file) in the head element and, if so, to put in a document-level handler for things where possible (you can do this with click events, for instance) which basically queues up or disables the click during that very brief period of time. That way, if JavaScript is enabled, you'll avoid the race condition, but if it isn't, any unobtrusive fallback you have in place will work.
The whole HTML file is executed in the order it is written, that means
<html>
<div id="ID"></div>
<script type="text/javascript">
document.getElementById('ID').innerHTML = "HELLO";
</script>
</html>
changes the contents of the div, wherease
<html>
<script type="text/javascript">
document.getElementById('ID').innerHTML = "HELLO";
</script>
<div id="ID"></div>
</html>
does not, because the JS code is executed before the div has loaded.
EDIT: If you want the JS to run after the page has loaded use window.onload or document.body.onload or
<body onload="...">
Alternatively if you're using a JS library such as jQuery, you can use
$(document).ready(function() {
...
});
Put them as functions in its own .js file which you include by <script src> at end of HTML <head> or <body>. If any of them needs to be executed during document load, call it using window.onload or whatever load function the JS library/framework offers, if you are using any.
As to the exact location, putting them in end of <head> allows them to be downloaded before the HTML page is been shown in browser and putting them in end of <body> allows the page to be shown a tad sooner because downloading the scripts will block the page rendering, thus it's a better speed experience.
However, IMO, it's a bit more robust to have the scripts downloaded before the page is rendered whenever you have some page elements which cannot be used without JS. In case of an impatient user this would otherwise lead to unusable elements.
I'd put it in a separate .js file and wrap the code so it is executed after the DOM is loaded. If you use a framework like jQuery or Prototype this should be easy.
For best performance place your JavaScript files at the BOTTOM of the HTML page you are serving.
To ensure that everything is set when you try to use it, execute only after the DOM is ready (there are multiple variations of this, my advice: Use a JavaScript Library).
You can put a script tag in the head, body, between the two, and more. You can put it most places but see this for a more in depth look.
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.
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. ^