I'm experiencing the documented bug where webkit browsers render the page incorrectly on first load because the javascript is executing before the css has finished downloading (due to them being downloaded in parallel).
While a quick refresh fixes the look of the page, that solution is inadequate for my problem (I run command-line utilities that take screenshots of our pages, but these utilities don't have the option to "refresh" a page before taking the screenshot)
Does anybody have any suggestions or solutions for ensuring that the css-include is loaded in it's entirety before the javascript-include and inline-javascript are executed?
Thanks! -Dan
EDIT-- Not using a library. Just good 'ol javascript.
If you are using a library I think most of them allow you to do this. It's easy with jQuery, if not you can use a <script defer="(x number of second)">Function()</script> at the end of hte page. You may also consider moving the javascripts to the bottom of the page where possible. js Best Practices.
+1 for putting your scripts at the bottom of the page, also might try putting your script in the window.onload event:
<script >
function myCode(){
// do something
alert('test');
}
window.onload = myCode;
</script>
I'm not 100% sure whether the onload event will wait until the .css file is loaded though. but it's easy to try.
Related
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>
Currently it's advised to load <script> tags as close as possible to </body> closing tag.
I'm creating a web widget ( something similar to the like button of Facebook ) and i was wondering if this is the same case.
<script src="http://localhost/wordpress/?ai1ec_requirejs_widget"></script>
After all this script will load a really tiny script which in turn will bring in everything that's needed for my widget through require.js, wouldn't it be better if it started loading as soon as possible?
It will still work. This is more of a best practice than a technical requirement.
The only things affecting the decision of where to put javascript are
Dependencies / order of execution
Loading time
Best practice (which is largely due to load time)
It's advisable to load large chunks of javascript at the bottom of the page, for example jQuery, however if you load jQuery at the bottom of the page if you have any code with $ above the call to jQuery it will not work as $ has not been defined.
So in your case if it's only a small amount of code, it doesn't really matter so long as it's not being called before any dependencies.
Hope that helps.
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
It is widely recommended that JS files should be put at the bottom of page to allow html codes to be loaded first. In this case, visitors will see something when waiting for full load of the page. However, I think this is disadvantageous for these reasons:
Modern design mainly depends on JS. This means before loading JS, the page will look ugly.
If interrupting the connection during the load (not loading JS at all), visitors will miss some of the website features (probably very important); and they will not understand that this is the problem of load (to re-load the page).
If the server-side script die (due to an error) at the very end of script before footer (e.g. in PHP), visitors will miss the whole page functionality (by JS); but if loading JS at the top, they will only miss the footer or half the page.
If loading JS first, browser will load other stuff (like images) in parallel; but if loading JS last, it may increase the load time. Because JS files are large (e.g. JQuery and JQuery UI), and all tiny stuffs (like images) have been loaded and we are loading a large file, last in line.
UPDATE: 5. Since jQuery library should be loaded before codes; if loading the jQuery library in footer (e.g. footer.php), you cannot add custom jquery codes for different pages (within the body).
Please correct me if I'm wrong! Is putting JS files in footer still beneficial?
Edit: I am adding another point in response to the cotton I'm seeing in peoples ears on this topic.
Additional point #5. If you are seriously concerned about handling behavior on JS-fail and by that I mean, people browsing with JS turned off, what you should be doing is embracing the notion of progressive enhancement. For instance, you could design an accordion menu to act as a flyout-menu on-hover by default, yes with CSS only, and then remove that behavior by changing key classes when JS is enabled. That way users have access to the links without JS if they should turn it off but they get the enhanced behavior when JS is working.
But what you should not be trying to handle is the absence of entire JS files on pages that are supposed to have them because the page was mangled on the back-end. Handling the unexpected is one thing, but handling the failure to finish building an HTML file before it's served should not ever be considered an acceptable scenario in production, especially if you have actual back end code in your templating language (which you shouldn't) waiting to spill out and give would-be hackers something potentially interesting to look at. Broken pages should be served as error messages.
================================
Dead wrong. Any time you use JS to tweak the initial static look of your page, you're doing it wrong. Maintain that separation of concerns and your pages will be much more flexible. Using JS to tweak the STATIC styles of your pages isn't modern, it's bass-ackwards and you can tell the jQuery mobile guys I said as much. If you absolutely must support IE6 and IE7 and IE8 tell your client how much it's going to cost them to cut out rounded gradient corners all over the place if they refuse to accept anything as an alternative to absolute graceful degradation for 5% of their client-base.
If your pages, with no JS beforehand are taking that long to load, you have other problems that need to be addressed. How many resources are you loading? What ungodly pre-processing is your PHP up to? I call back end or design shenanigans.
Are you saying it's half-acceptable to have half a page with working JS rather than completely unacceptable? Don't let go of that client, whoever they are.
jQuery, when minimized is about the size of a medium-sized JPEG.
Note: It is not entirely unacceptable to have some JS up top. Some specialized code like analytics stuff or canvas normalizers require it. But anything that doesn't need to be should be at the bottom. Every time JS is parsed, the entire page load and flow calculation process stalls out. Pushing your JS to the bottom improves perceived page load times and should also serve to provide evidence that somebody on your team needing a swift kick in the butt to figure out why their code is tanking or what could be done with their 25 megabyte png-24s that they just shrunk down rather than reformatted.
Script tags in the header block all other requests. If you have let's say 10 tags like this:
<script src="http://images.apple.com/home/scripts/promotracker.js"></script>
...they will be executed sequentially. No other files will concurrently be downloaded. Hence they increase page load time.
Check out HeadJS here as a sample solution.
You need to think in terms of "do I need the DOM to be ready before I execute some javascript". Basically you put script tags at the bottom of the page to basically guarantee that the DOM is ready. If you link your styling in the header, and properly style the page, you shouldn't get the "ugliness". Secondly, if you are dependent on some parts of the page to be displayed with javascript to work on DOM objects, I would use more ajax calls to prevent this problem as well. The best of both worlds. Page is loaded with what you can, and then ajax calls are getting the html to populate on other parts of the page.
The reason putting JS at the bottom of the page or loading in asynchronously is recommended is that JS slows the page load down.
If some browsers downloading the JS blocks other parallel downloads, and in all browsers executing the JS blocks the UI thread and hence rendering (parsing blocks in some too).
Putting it a the bottom or loading asynchronously attempts to delay the issue until it has less impact on the visitors page load experience.
Don't forget that no matter how beautiful you page is, is it takes too long to load people won't wait and 2 /3 seconds is where it starts to cause problems.
Modern design can probably depends less on JS that it ever has - yes we need polyfills still but as browsers get better then we can do more with CSS
This might be true for things like Backbone.js apps, but if the lack of JS breaks the site then I'd argue the design should be different.
If the server-side script dies there are perhaps other issues to worry about, there's no guarantee there's enough of the page to be useful anyway.
NO! JS blocks the UI thread and in some cases downloads so the images will be delayed. Also as the JS is using connections then there are less connections available for parallel downloads.
Have a look at #samsaffron's article on loading jQuery late - http://samsaffron.com/archive/2012/02/17/stop-paying-your-jquery-tax
If you can delay the JS load you should
I have occasionally recommended putting Javascript at the bottom of a page (just before </body>) but only in circumstances where a novice programmer couldn't really cope with window.onload or <body onload...> and that was the easiest adaptation of their code to get it to work.
I agree with your practical disadvantages, which need to be balanced against Michael's note of the effect on load time. In most cases [I submit] loading scripts in the <head> of the page wins.
Everybody's needs are different, lets go through your list:
1) I've never had an issue with the layout or styling of the page because of javascript. If you have your HTML & CSS in order the missing javascript will be close to invisible.
You can hide elements in the css and display them with javascript when they're ready. You can use jQuery's .show(); method
here's an example:
<!DOCTYPE html>
<html>
<head>
<style>
div { background:#def3ca; margin:3px; width:80px;
display:none; float:left; text-align:center; }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<button id="showr">Show</button><button id="hidr">Hide</button>
<div>Hello 3,</div><div>how</div><div>are</div><div>you?</div>
<script>
$("#showr").click(function () {
$("div").first().show("fast", function showNext() {
$(this).next("div").show("fast", showNext);
});
});
$("#hidr").click(function () {
$("div").hide(1000);
});
</script>
</body>
</html>
If you still have problems you can split up your javascript into ones your site relies on and other scripts and put some in the header and some in the footer.
2) That's user error, you can't control that, but you could check if the needed functionality is there and attempt to reload it. Most plugins offer some sort of confirmation if they're running or not, so you could run a test and try to reload them.
You can also delay loading of files until the user needs them, like waiting for them to focus on a form to load validation scripts or scroll past a certain point to load the code for things below "the fold"
3) If the page dies you're going to get a half-blank page anyhow. With PHP 5 you can do better error handling with exceptions
if (!$result = mysql_query('SELECT foo FROM bar', $db)) {
throw new Exception('You fail: ' . mysql_error($db));
}
and this
try
{
// Code that might throw an exception
throw new Exception('Invalid URL.');
}
catch (FirstExceptionClass $exception)
{
// Code that handles this exception
}
catch (SecondExceptionClass $exception)
{
// you get the idea what i mean ;)
}
4) If you minify your script you they shouldn't be much larger than images. JQuery is 32KB minified & gziped. JQuery-UI's script is 51KB. That's not too bad, most plugins should be even smaller than that.
So I suggest you should do what you have to do to get the results you want, but search for best practices that reduce errors and excess code. There's always a better way to skin a cat...
I'm not really that familiar with putting the scripts in the footer, but you may want to look into the various ways of telling the page to only run the JavaScript AFTER the page is fully loaded.
This opens up a couple options - you could have JS dynamically load external scripts only after the page is ready.
You can also hide some or all of the page content, and then just make it visible after the page is ready. Just make sure you hide it with JS, so that non-js browsers can still see it.
See these:
https://www.google.com/search?q=javascript+page+ready
http://api.jquery.com/ready/
Currently I'm doing this.
<js>
</head>
Pagespeed and other articles suggest doing this instead.
<js>
</body>
</html>
I would love the opinion of stack overflow!
Thank you
The only issue with putting all your scripts at the end of the body is that sometimes page components drop little bits of Javascript on the page that may assume the existence of some Javascript facility. Other than that, there's nothing wrong with it and it can help make your pages appear to load/render faster.
You might also look into tools like LabJS (http://labjs.com) as a more sophisticated way to load your Javascript.
Use progressive enhancement so that your page will work whether JavaScript is enabled or not. Then, move the Javascript to the bottom of the page so that your page's content loads and renders first. And, as always, test the performance of your page using Page Speed or YSlow.
The default way of including Javascript is to do it from the head tag, that's where they normally belong. That's where you should start out, and only move the scripts if you need to optimise the loading of the page.
There are some reasons to put some scripts later in the page:
To make the content of the page load earlier
To make the page less sensetive to slow loading external scripts
There are some special considerations if you move scripts down the page:
Some scripts doesn't work if the load after the content.
You should make sure that the content doesn't look bad or does anything nasty if the user tries to use it before the scripts are loaded.