Javascript embed code that doesn't halt page rendering - javascript

I'd like to embed a number from another page. The remote call is small (only returns a number) but I would like the page to keep loading while the request is out. How should I do it? I'm currently doing
<span id="target">Loading ...</span>
<script>
var cb = function(data) {
document.getElementById("target").innerHTML = data;
}
</script>
<script src="http://webnumbr.com/webnumbrs.latest.json(callback=cb)"></script>
I'm open to client side or server side changes. Just the least code for the client embed the better

The "official" recommendation (see rules) is to put all JavaScript at the very bottom of the HTML file. The contents of every tag will be evaluated before rendering continues, as the outcome of the script might affect further rendering (think of document.write()).

Honestly,
I think the best way may be to simply put it in an onLoad() instruction so it doesn't load until the document has fully rendered. It's similar to Tom's answer but in this case you will eliminate the majority of the DOM issues you're experiencing.

I believe you are using AJAX to load the content from other page on loading the current page, make sure that your AJAX call is asynchronous, and update the "webNumbr_webnumbrs" control only after successfull completion.

Related

How to stop some javascript file from loading?

Some third party javascript is included in my HTML page.
It adds some sharing buttons to my webpage, and is called as like
<script src=http://something/something.js></script>
But sometimes I would like not to load this javascript at all. It could be solved on the server side, which would block, under some conditions, the above mentioned line from appearing at the webpage. But this is not possible to remove this tag from the HTML at all due to technical reasons, neither by server side (like PHP) nor by javascript (eg. by using document.write to put the tag there only when needed). I need to resolve this in javascript only, and I need to BLOCK the script tag if condition is met, meaning the tag always exists in the HTML.
Is there any possibility to block the something.js URL mentioned above from loading? So I would, for example, execute some other javascript before or after it. I thought that it would be possible this way, but it doesn't seem to work:
<script>
(function(){
var scripts=document.getElementsByTagName('script');
for (var i=0; i<scripts.length; i++)
if (scripts[i].src && scripts[i].src=='http://something...')
scripts[i].parentNode.removeChild(scripts[i]);
})();
</script>
<script src=http://something/something.js></script>
This doesn't work because when the script is called, it cannot see another <script> tag below at that moment. If I put the script below, it detects the script with src attribute, but it is too late to remove the element since it has already executed (and pasted sharing button elements to the webpage).
Is there any other way to stop loading of the third party script? Thank you
EDIT: updated the fact that the third party javascript needs to be in the HTML every time due to some internal reasons (despite the fact I disagree with that, I can do nothing about it).
a simple solution could be:
<script>
if(yourcondition){
document.write('<script src=\"http://something/something.js\" type=\"text/javascript\"><\/script>');
}
else{
document.write('<script src=\"http://something/OTHER.js\" type=\"text/javascript\"><\/script>');
}
</script>
yourcondition can be a boolean stored in a cookie or localstorage. Or you can set it to true or false depending your needs.
Also note that the source value in your script tag must be encapsulated between "
If the script relies on being in the document during the initial parsing because it outputs HTML where it appears (e.g., via document.write), as it seems to from your hidemeifnecessary example, then your "hide me" approach is probably the best you can do client-side.
If the script didn't need to be in the page during the main parsing, you could lazy-load it, but from your question that doesn't seem to be the case.
As you said in the question, the right answer here really is to deal with this server-side.
You have to make sure your script is loaded as soon as possible. I load mine right after the opening head tag. In that script select all tags you want to block (in my case script, iframe and img) and iterate through them. Add the event listener "beforescriptexecute" to them and trigger preventDefault like this:
bsePd = element.addEventListener('beforescriptexecute', e => {
e.preventDefault();
e.target.removeEventListener('beforescriptexecute', bsePd);
console.log('Prevented script from execution:', e.target.src);
});
With that you catch already existing scripts. For those added dynamically you can add the event Listener DOMNodeInserted and wait for them to come.
Thats how I made a cookie consent manager I needed for a site where it was not possible to do it whit PHP because of heavy caching mechanisms.

Dynamic part of web app based on REST API

We have web application which sends REST API request and change the DOM after request is completed. It is all done in jQuery with AJAX calls. But the problem is, all of the dynamic parts of a page has a slight delay to get updated on page refresh. It's like you first see the static elements and then immediately it gets updated. It is noticeable quite a lot.
We wait for $(document).ready so I think that is the issue. Is there a better way of updating HTML before it gets rendered so the user won't notice the change?
Not to mention, most of the data are cached in sessionStorage so it could be read without REST call.
I searched a little bit but I'm not quite sure, do I need a client-side template engine for this? Like Mustache.js?
I don't think it it possible to completely avoid delays caused by ajax requests. You could possibly put some request out of $(document).ready and place it in a head section:
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
// some javascipt here, $.getJSON etc.
</script>
</head>
In this case you have to look out for selecting elements that are not rendered yet (this could cause some unpleasent errors).
Finally I would recommend you to use some loading gif and animations of loaded elements in order to increase user experience. Take a look for example at AngularJS and its animation features here: https://docs.angularjs.org/tutorial/step_12
If all you're worried about is the noticeable change when the page updates, you could put everything inside your body tag inside a container div and give it display:none;. Display a loading image on page load then show the container div when the Ajax request is complete.

Javascript onload after redirect

in my Javascript code I am loading a page, and then would like to perform some functions. I tried to use solutions like window.onload, but that is after my html (blank page with just the JS) loads, I need the function to perform after the page I am reffering to is loaded.
I am using this code:
this.document.location.href = myurl;
And after this loads, I would like to call some function. Is there a way to do so?
Thanks
EDIT:
I can not edit the target page source code.
When you change the value of document.location.href, you are essentially doing a redirect.
You can either just do whatever you want to do within the loaded page itself or if you don't have cross domain issues, do xhr of the page you're wanting to load dynamically, query the body, replace content of your current body and also replace head contents i.e. style, title and scripts etc. You could then execute any script you want.
Extra note: This is quite a tricky thing to do, I've done this a few times before - and its proven quite problematic due to the fact that you don't actually get a fully parsed document object that you can just query so simply, you only receive a huge string. One hack that I've thought of using is actually just loading everything within an iframe allowing easy querying which is actually documented - extra reading here
window.load takes forever to fire because it waits for all images and assets to load on the page.
It sounds like the best solution for you would be to poll for the document to be finished loading. Here's a simple example:
(function poll(){
if(document.readyState === "complete"
{
// Your code here
}
else
setTimeout(poll,500);
})();
Place the 'window.onload = myFunction(){...}' inside the page, which will be loaded.
this.document.location.href
will open the page like you typed it into the browser address bar and your onload-script in the old page will not be executed in the new one.
By the way, you can shortcut it to document.location = myUrl
See the Document-API at Mozilla

Javascript non-blocking scripts, why don't simply put all scripts before </body> tag?

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.

Is it OK to put javascript code anywhere in HTML code?

I see that Javascript code is normally in heading part of HTML code.
<head>
<script type="text/javascript" language="javascript" src="core.js"></script>
...
</head>
Is it OK to put the Javascript code in a body part of HTML code? I tested it, but it seems to work.
<body>
<script type="text/javascript" language="javascript" src="core.js"></script>
...
</body>
If so, why the examples of Javascript books put the javascript code in heading part?
If not, what's the difference between putting the javascript code in body/heading part?
Not only is it OK, it's actually better, since it lets the content come first.
If your viewers have a slow (eg, mobile) connection, it's better to send the actual content first, so that they can read it while the browser downloads the Javascript.
All the people saying it is better only applies if you are talking about at the bottom of the page (and that is an up for debate thing) from a code quality point of view, it is NOT ok to sprinkle script tags through your html. All references to javascript should be in a single place on the page, either the head (where they should be), or the very bottom (as a perf optimization)
Edit:
Basically, a web page is made up of 3 pieces; style (css), structure (html), and behavior (javascript). These pieces are all very distinct, so it makes sense to keep them as separate as possible. That way if you need to change some javascript, it is all in one place. If it is sprinkled through the file, it becomes much more difficult to find the code you are looking for, and that code basically becomes noise when you are just looking at structure.
It is the same arguments as why not sprinkle db access code all over your page. It has nothing to do with technical reasons, purely an architectural/design decision. Code that does different things should be kept separate for readability, maintainability, and by extension, refactorability (not sure if that last one is actually a word...)
You can do it, and people often do.
For example, people like to put their script tags just before the closing </body> to make web pages render quicker.
Also, if you do a script block after an element is created, you don't need to wait for DOM ready.
Be warned though, don't add, or remove an element from an unclosed ancestor in the markup tree (not including the script block's immediate parent element), or you will get the dreaded Operation Aborted error in IE.
Just something to add on:
I have preference of putting Javascript file right before </body>. My reasons being that:
Content can load and be shown first. If you load huge Javascript files first, which most are meaningless until the page is loaded, the user won't be able to see anything until the JS files are loaded.
Most Javascript code require to work with the UI can only run after the UI has been loaded. Placing the codes at the end of the html file reduces the need to use the onload event handler.
It is very bad habit to place Javascript snippets all over the HTML file. Placing all at the back of the HTML file allows you to manage your Javascript more efficiently.
It is legal according to the spec.
Most examples use them in the header as the headers come first and the browser will be able to parse the reference and download the JS files faster.
Additionally, these are links and are not part of the display, so traditionally, put in the header.
It is perfectly legal but there seem to be some differing opinions about it. Those who say to put all the javascript references in the head argue that the script is downloaded before the rest of the page become visible and dependent on it. So your user will not see an object on screen, attempt to interact with it and get an error because the javascript code is not yet loaded.
On the other hand, the argument goes that it takes longer to load all the script before the user sees the page and that can have a negative impact on perceived speed of your site.
JavaScripts inside body will be executed immediately while the page loads into the browser
Placing javascript at the end of the body will defer javascript load (ie: the page will render faster), but remember that any javascript function used for an event should be loaded before the event declaration, it is mainly because users may be able to fire an event before the page is completely loaded (so before the function is loaded)!
I used to put it in the head, then I've heard that it takes longer for the page to load so I started placing the scripts at the very bottom. However, I found out the most 'clean' way to do it is to place it in the head BUT you place the script inside a document.ready function. This way you have the best of both worlds. It is cleaner because it is in the head and it is not loaded before the content has been loaded, so there aren't any problems performance wise either.
With jQuery for instance, you can do it like this:
$(document).ready(function() {
alert('test');
});
The alert will only popup when the page has been fully loaded, even though the script is in the head.

Categories

Resources