On my website I have ads from a network that does not load particularly fast. Some browsers won't draw the page unless the ads load, making the website appear slower than it actually is - is there any way to prevent this? As in mark the script as non-essential or do some javascript trick to only draw it once it's loaded? I tried googling a solution, but to no avail.
Also, some ads are added to the site as iframe, some as JS script (much like adsense)
If loading the ads is optional, what you could do is wait to load them and then use ajax to load/add them later with jquery.
The best thing to do here is defer the loading of your ads, and anything else non-essential, until after the page has finished loading.
Attach code to load these to window.onload. That event fires when everything on the page is done loading. You can even defer loading the whole script by adding it to the DOM later. I use jQuery.getScript() for this, but there are other methods.
Load the ad after the DOM has been loaded. You would have your page load normally, then bind a function (JavaScript) which injects the ad(s).
There is also the defer attribute on tags, but it isn't fully cross-browser supported.
JavaScript: Defer Execution
You could try to put your script tags at the bottom of the page, before the closing body tag. http://developer.yahoo.com/blogs/ydn/high-performance-sites-rule-6-move-scripts-bottom-7200.html
Or you could try to load them asynchronously.
In HTML5 (not as much browser support)
<script async src="http://your.com/script.js"></script>
Another way (works with more browsers)
<script>
var resource = document.createElement('script');
resource.src = "//your.com/script.js";
var script = document.getElementsByTagName('script')[0];
script.parentNode.insertBefore(resource, script);
</script>
http://css-tricks.com/thinking-async/
Related
I am loading some JS from an external source right before my </body> tag. I am experimenting to see what happens if the server hangs while trying to serve this third party JS. It seems that everything on my page works just fine, but the browser still spins as though the page is still loading. Is there a way to load this javascript in such a way that the browser won't wait on it to declare the page fully loaded?
For reference, I have tried the following two methods to load my JS asynchronously:
<script>
var resource = document.createElement('script');
resource.src = "https://myserver.com/js/myjs.js”;
var script = document.getElementsByTagName('script')[0];
script.parentNode.insertBefore(resource, script);
</script>
and
<script async src="https://myserver.com/js/myjs.js"></script>
An answer compiled from the comments above and my own experimentation:
If you load the third party JS after the rest of the page has finished loading, then the browser will render the page as though it is completely loaded, even if the external resource hangs. One way to accomplish this is to load the JS within a window.setTimeout with a timeout greater than your page's standard load time.
When you are loading external JS through a JS function rather than through a standard script tag, remember that if you have any data- attributes, they belong in the resource.dataset object.
So, in the example above,
<script async data-my-data="someData" src="https://myserver.com/js/myjs.js"></script>
becomes
<script>
window.setTimeout(function () {
var resource = document.createElement('script');
resource.dataset.myData = "someData";
resource.src = "https://myserver.com/js/myjs.js";
var script = document.getElementsByTagName('script')[0];
script.parentNode.insertBefore(resource, script);
}, 5000);
</script>
Note that 5000 as a timeout works for me because my page loads in well under 5 seconds, and I don't need the JS that I am loading in the first 5 seconds. If you need yours sooner or your page takes longer to load, you will need to adjust this number. Also, as #adeneo mentioned above, another way to accomplish the same thing would be to load the js through ajax later.
You can load js by getscript, check this demo
What are the differences between the two solutions below ?
In particular, is there a good reason to favour 2 over 1. (note: Please assume the name of the script to load is known. The question is just about if there is value in creating a minimal script to load a script in the given situation )
1 - Script At The Bottom
<html>
<body>
...
...
<script src='myScript.js'></script>
</body>
</html>
2 - Script at the bottom loads external script
<html>
<body>
...
...
<script>
// minimal script to load another script
var script = document.createElement('script');
script.src = 'myScript.js'
document.body.appendChild(script);
</script>
</body>
</html>
One important feature of the second one is that it allows the browser to finish parsing the page immediately, without waiting for the script to load. That's because the first example allows the script to use document.write to change the parsing state around the <script> tag, while the second one doesn't.
Now, we know that it's at the bottom of the page so that there isn't any important content left to parse, but this is still an important difference. It's not until parsing is done that the browser fires the popular DOMContentLoaded event. In method 1, the event fires after the script loads and executes. In method 2, the event fires before the script starts loading.
Here are some examples. In these demos, a DOMContentLoaded listener changes the background color to yellow. We try to load a script that takes 3 seconds to load.
http://jsfiddle.net/35ccs/
http://jsfiddle.net/VtwUV/
(edit: Maybe jsfiddle wasn't the best place to host these demos. It doesn't show the result until the slow-loading script loads. Be sure to click Run again once it loads, to see what happens.)
Pick the approach that's best for your application. If you know you need the script to run before DOMContentLoaded, go with method 1. Otherwise, method 2 is pretty good in most cases.
1. Script at the bottom
When you use a "synchronous" script tag, it will block the browser from rendering the page until the script is loaded and executed. This method has the following effects:
Regardless of where you put the script tag, the browser cannot fire DOMContentLoaded until the script is downloaded and executed.
Placing such a script tag at the bottom only ensures that the browsers has rendered all content before getting blocked by the script.
2. Script at the bottom loads external script
When you inject a script tag using JavaScript, it will create an "asynchronous" script tag that does not block the browser. This method has the following effects:
Regardless of where you put the JavaScript code that generates the script tag, the browser executes it as soon as it is available without blocking the page. The DOMContentLoaded fires when it should; irrespective of whether the script has downloaded/executed.
The second approach has the following advantages:
The script that injects a script tag can be placed anywhere including document head.
The script will not block the rendering.
DOMContentLoaded event does not wait for the script.
The second approach has the following disadvantages:
You cannot use document.write in such scripts. If you do, such statements might wipe the document clean.
Asynchronous execution does not mean that browser has finished parsing the page. Keep the script executes as soon as it is available clause in mind.
Execution order is not guaranteed. Example: If you load "library.js" and "use-library.js" using injected script tags, it is possible for "use-library.js" to load and execute before "library.js".
Having said all that, there is another method for loading scripts, with three variations:
<script src="myScript.js" async></script>
<script src="myScript.js" defer></script>
<script src="myScript.js" async defer></script>
Regarding Steve Souders's work: he proposed 6 techniques for loading scripts without blocking. The async and defer attributes introduced in HTML5 cover the Script DOM Element and Script Defer techniques and their browser support is more than enough for you to worry about the other techniques.
These two ways of initializing a script are basically the same, although theres no reason to use the second way if you can directly put in the result. However you can wrap the second example in a $(document).ready() method for example which would lead to sort of a lazy loading effect. This basically means that the page would load first and after the loading of the page is finished it would load the script. Or of course you can create a method which initializes a certain script this way. It's useful when you have a large script which is used only in some situations. This would prevent loading it unless you need it, thus decreasing the overall loading time.
This isn't a direct answer to your question, but it's good to know regardless.
The 2nd approach is sometimes used as a library fallback.
For example, you load jQuery from the Google CDN. But, if it were to fail for any reason, load jQuery from your own local copy.
Here's how the popular HTML5 Boilerplate recommends doing this:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.11.0.min.js"><\/script>')</script>
The first method means that the script tag is hardcoded in. The second method dynamically adds a script tag to the bottom of the page using JavaScript. The benefit of the second method is that you can add additional logic if needed to modify the script tag. Perhaps you might want to load a different script file based on culture, browser or some other factor you can determine in JavaScript. The second method also causes the JavaScript file to be loaded without blocking the loading of the rest of the web page. In method one the page will stop loading when it gets to the script tag, load the JavaScript file, then finish loading the rest of the page. Since this tag is at the bottom of your page it doesn't make too much of a difference.
If you are creating a Windows Store app using JavaScript then the first method is recommended as this will allow the app to bytecode cache the JavaScript file which will make it load up faster.
In order to avoid javascript to block webpage rendering, can't we just put all all our JS files/code to be loaded/executed simply before the closing </body> tag?
All JS files and code would be downloaded and executed only after the all page has being rendered, so what's the need for tricks like the one suggested in this article about non blocking techniques to load JS files. He basically suggests to use code like:
document.getElementsByTagName("head")[0].appendChild(script);
in order to defer script laod while letting the webpage to be rendered, thus resulting in fast rendering speed of the webpage.
But without using this type of non-blocking technique (or other similar techniques), wouldn't we achieve the same non-blocking result by simply placing all our JS files (to be loaded/executed) before the closing </body> tag?
I'm even more surprised because the author (in the same article) suggests to put his code before the closing </body> tag (see the "Script placement" section of the article), so he is basically loading the scripts before the closing </body> tag anyway. What's the need for his code then?
I'm confused, any help appreciated, thanks!
UPDATE
FYI Google Analytics is using similar non-blocking technique to load their tracking code:
<script type="text/javascript">
...
(function()
{
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = 'your-script-name-here.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s); //why do they insert it before the 1st script instead of appending to body/head could be the hint for another question.
})();
</script>
</head>
Generally saying no. Even if scripts will be loaded after all the content of the page, loading and executing of the scripts will block the page. The reason for that is possibility of presence of write commands in your scripts.
However if all you want to achieve is the speed of loading page contents, the result of placing script tags right before </body> tag is the same as for creating script tags dynamically. The most significant difference is that when you load scripts in common static way they are executed one by one, in other words no parallel execution of script file (in old browsers the same true is for downloading of the script too).
If you want asynchonous scripts.
Use the (HTML5) async tag if it is availble in the browser you're in. This is what Google Analytics is doing in the code you posted (specifically the line ga.async = true MDN Link, scroll down for async).
However, this can cause your script to load at arbitrary times during the page load - which might be undesirable. It's worth asking yourself the following questions before choosing to use async.
Don't need user input? Then using the async attribute.
Need to respond to buttons or navigation? Then you need to put them at the top of the page (in head) and not use the async tag.
Async scripts run in any order, so if your script is depending on (say) jQuery, and jQuery is loaded in another tag, your script might run before the jQuery script does - resulting in errors.
Why don't people put things at the bottom of the body tag? If the script is taking enough time to load that it's slowing/pausing the load of the website, it's quite possible that that script is going to pause/hang the website after the website has loaded (expect different behaviour on different browsers) - making your website appear unresponsive (click on a button and nothing happens). In most cases this is not ideal, which is why the async attribute was invented.
Alternatively if your script is taking a long time to load - you might want to (after testing) minify and concatenate your script before sending it up to the server.
I recommend using require.js for minifying and concatenation, it's easy to get running and to use.
Minifying reduces the amount of data that needs to be downloaded.
Concatenating scripts reduces the number of "round-trips" to the server (for a far away server with 200ms ping, 5 requests takes 1 second).
One advantage of asynchronous loading (especially with something like the analytics snippet) is, at least if you would place it on the top, that it would be loaded as soon as possible without costing any time in rendering the page. So with analytics the chances to actually track a user before he leaves the page (maybe before the page was fully loaded) will be higher.
And the insertBefore is used instead of append, because if I remember correctly there was a bug (I think in some IE versions, see also link below theres something in the comments about that).
For me this link:
Async JS
was the most useful I found so far. Especially because it also brings up the issue, that even with googles analytic code the onload event will still be blocked (at least in some browsers). If you want this to not happen, better attach the function to the onload event.
For putting the asynchronous snippet on the bottom, that is actually explained in the link you posted. He seems to just do it to make sure that the DOM is completely loaded without using the onload event. So it may depend on what you're scripts are doing, if you're not manipulating the DOM there should be no reason for adding it on the bottom of body. Besides that, I personally would prefer adding it to the onload-event anyway.
i would like to load jquery.js after the window.onload event has been fired by browser (reducing load time)
Doing that maybe with appendChild the problem is i can't use anymore $(document).ready();
Is there a way to use something equivalent to .ready after the loading of jQuery (after the window.onload?)
thanks
Just place <script>s at the bottom of your HTML files. If you load jQuery right before the closing </body> tag, page rendering isn’t blocked while jQuery is loading.
It doesn’t matter if you speed up window.onload if you’re not gonna use it anyway. E.g. if you use…
$(document).ready(function() {
// …
});
…or its shorter alias…
$(function() {
// …
});
…internally it’s not relying on window.onload, but on DOMContentLoaded.
Loading scripts at the bottom is gonna help you much more than waiting for window.onload to start loading your scripts.
I think you can't. In order to use jquery as well as other plugins that developed from jquery, you have to load jquery.js first of all. (in the part, you have to put the script that load jquery.js on top)
It doesn't even work if you load (Slider, Thickbox, DatePicker...) first then jquery.js
^^
first of all load jquery from here
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js">
loading it from google means the user most likley already has it cached resulting in a much quicker load.
also to be honest jquery isnt that big a file (less than a meg) so it shouldnt really affect load times.
all script tags should be at the bottom of your page in anycase.. so loading times wont be affected.
content
script tags
otherwise you could do something like
if ($.jquery){
document.body. and then my js gets rusty... but basicaly append the script tag
I don't understand the reason for replacing this:
<script src="js/example.js"></script>
with this:
$.getScript('js/example.js', function() {
alert('Load was performed.');
});
Is there a particular reason to use the jQuery version?
The only reason I can think of is that you get the callback when the script is loaded. But you can get that callback using a script tag, too, by using the load event (or on really old IE, onreadystatechange).
In contrast, there are several negatives to doing it this way, not least that getScript is subject to the Same Origin Policy, whereas a script tag is not.
Even if you need to load a script dynamically (and there are several reasons you might need to do that), frankly unless you really need the callback, I'd say you're better off just loading the script by adding a script tag:
$('head:first').append("<script type='text/javascript' src='js/examplejs'><\/script>");
(Note: You need the otherwise-unnecessary \ in the ending tag in the above to avoid prematurely ending the script tag this code exists within, if it's in an inline script tag.)
script tags added in this way are not subject to the Same Origin Policy. If you want the load callback, then:
$("<script type='text/javascript' src='js/examplejs'><\/script>")
.on("load", function() {
// loaded
})
.appendTo('head:first');
(As I said, for really old IE, you'd have to do more than that, but you shouldn't need to deal with them these days.)
I can think of three reasons you might use the jQuery form:
You want all of your script declarations at the top of your document, but you also know that placing script declarations there forces the browser to download them in their entirety before proceeding further in the page rendering process. This can introduce measurable delay. The jQuery form will schedule the script loads until after the document is finished downloading, similar to the effect of placing all of your <script> tags at the end of the document, only without the syntactic weirdness.
The <script> mechanism is not available to scripts that do not live in the HTML document itself; that is, if a script included on the page with <script> wants to load a script, it has no option but to use a JavaScript-based approach, such as calling the jQuery function.
The jQuery form allows notification of the script's successful execution, in the form of a supplied callback function.
No need to do that..
You do that if you want to load the script dynamically (when needed, and not from the beginning)
The script might depend on jQuery, so it would be a way to prevent the browser trying to load it if it hasn't loaded jQuery.
There are a number of reasons that jQuery might not load, from a simple network failure to a CDN not being whitelisted by a NoScript user.
maybe to control when a script is loaded? On a javascript heavy page, it may be worth waiting to load some things that are non essential until after essential things are loaded.