I read this nice article on how external scripts block the UI thread but it wasn't clear to me whether the blocking is actually due to the presence of the <script> tag or the src='/myscript.js' src attribute.
My question is does inline javascript (lacking a src attribute declaration), for example this:
<script type='text/javascript'> alert('am i blocking too?');</script>
or this:
<script type='text/javascript'> var php='<?=json_encode($myObj)?>';</script>
also block the UI thread?
Any loading of a JS file or any execution of any JS (whether in an external file or inline) will block the UI thread.
The exception for the <script> tag is an asynchronous load where the script will load and execute asynchronously in the background.
There are also "deferred" loads (i.e. the defer attribute) which tells the browser not to actually execute the JS therein until the rest of the page has loaded.
Outside of web workers, which are their own beast, consider the HTML web page and associated Javascript as single threaded.[1]
Thus, if any javascript is running on the page, then the entire user interface is blocked. Things like window.alert(), window.confirm() and window.prompt() block the entire UI until they are cleared, but even an infinite loop will freeze the browser window[2] until it has finished.
EDIT -- based on comments and edit to the question:
The link provided in the original question doesn't refer to the execution of Javscript running, but the sync vs async nature of Javscript loading. I'll give you one example of why such blocking may occure.
In the way-back days of Javscript, the function document.write() was the only way to have Javascript interact with the web page. As such, when the web page came across a request for a Javascript file to load, the browser had to put everything else on hold -- just in case the Javascript file used document.write to inject something into the stream.
In today's world, this doesn't happen as much and so browsers give the page designer a way to say 'I promise this Javascript file doesn't care exactly when it is loaded and it won't use document.write() or anything else tricky. You don't have to freeze until it is done.
This is why modern web browsers have a defer and async attributes.
Opera is special, but we'll ignore that.
Or entire browser, depending
alert() or any other prompting actions will block the thread until the user responds to the prompt. No matter where they are...
Update ( regarding the comment ) :
A browser window parses the HTML and runs the JS with a single thread.. so anything in the javascript code that will take time to complete will block the thread.. no matter what it is.. It can be an alert or an AJAX Request or anything else..
Related
What are the differences in performance and memory footprint , if any, in these different approaches:
1. Using Src
<script type='text/javascript" src="1MBOfjavascript.js"></script>
2. Directly injecting in the Head
$('head').append("<script type='text/javascript'>1MBOfJavascriptCode</script>");
I'm interested because we are developing a Cordova App where we use the second method to Inject to the DOM a previously downloaded Javascript bundle read from the HTML Local Storage.
Given that the script will probably grow in size, I'd like to know if with the second method I could incur in some memory issues or other DOM problem.
I believe the overhead in such cases should be insignificant as the main processing/memory consumption is based on how the actual script works. Ie the memory used by file would be the total size of the script which is what 1MB at max? However during execution the same script can use up 100MB easily.
Anyways , coming to the point.
Plain text inclusion would be better if it has to be included in all cases as it skips a script execution and also does not cause re-rendering by browser after the append.
Append option should be used in cases where you only need the script under specific conditions on client side and do not load it un-necessarily.
The browser goes through all elements before to render the page so I would imagine it is exactly the same, if anything if you had scripts after the page is downloaded chances are that you will get errors of the type "call to undefined functions" if you call onto a function that you have added after the load.
My advise would be add them at load using src but keep things tidy.
Javascript impact a lot depending upon how and where you are loading your file, there are many ways to load a file or code.
First method you mentioned is an conventional way to load javascipt file that is load file using src and usually its loaded before closing </head> tag but now a days it is in trend to load file befor your </body> tag. it speeds up application load and prepare DOM faster.
second method is not obviously a good way to load javascript at first as there can be some code that should be working only after your DOM is ready and as here you are loading your javscript with javascript/jquery append which depends upon your jquery file loading which will delay your code execution. and there might be possible that some of your code will not have desired output (depending upon how you have called functions and how much they are dependent upon DOM ready )
I would prefer to load a javascript file with first method and at the bottom of the page/app if possible.
asyncrounous loading can also be tried.
i think because browser behavior after retrieving response from any web server
will try to parse all the elements first for building the DOm, after the DOM are ready then your script would be executed, based on this it is obvious its the main
reasons is which is the first
will be executed first than injecting it.
About the second method
i think javascript engine in each browser can handle that thing easily and withouth any problem. the engine does not care about the size actually it only about how long the script will be loaded and then executed. what will be the issue is when you try injecting any elements into DOM is when you try to do it in loop there might be a memory problem.
when you say big javascript files yeah we should think about the memory. but
about the method you previously said its just about which are executed first.
thats my opinion
I'm creating a web application that has multiple pages of content that I'm loading dynamically with AJAX and the HTML5 History API. When a user attempts to change the page, the new content is loaded with a $.get and injected into the body, like so:
$.get("somepage.html", function (data)
{
$("body").html(data);
});
Most of these pages require additional scripts to be loaded. This wouldn't be an issue except for the fact that $(document).ready fires before these scripts are loaded. Somepage.html looks something like this.
<script src='http://getjquerysomewhere/'></script>
<script src='my_script_that_depends_on_jQuery'></script>
This issue is complicated by the fact that these pages must have the ability to be loaded on their own. I'm therefore unsure how I can eliminate the $(document).ready functions without affecting this behavior as well.
How should I approach this problem?
What you are trying to do is certainly possible, but it's not going to be very maintainable in the long-run.
One of the biggest issues you'll run into is properly injecting the code from the ajax loaded html into the current page. You can't just ignore it and let it all run because then you'll be including libraries multiple times (resulting in plugins getting overwritten/removed), and the code for the page you are loading may happen too soon due to the dom already being ready.
This pretty much leaves you with two options: dependency injection or front-loading.
Dependency injection will probably be the easiest of the two for you to implement because it requires the least amount of changes to your current code-base. All you would have to do is ensure that all pages requested with ajax only include the content of the <body> (which can be done with server-side code), and ensure that all page-specific code is included before the closing </body> of each page. Then you would just have to use the dependency-injection methods to run your code with the proper dependencies.
You could also have it only include <div id="#content">...</div> for your partials, which ever makes more sense for your use-case.
Front-loading would be a little more difficult because you'll have this one giant file that has all of your code for all of the pages, unless you use a build process (if you've never used a build-process before, you really should try it, even if you don't think you need it.) With front-loading, you'll either have to use event delegation, or have init methods for each page that you selectively execute as you load each page. This could become a maintainability nightmare without good build processes.
You can call functions from the original scripts on the page which you have loaded. For Instance you could do this in your main:
<script>
function ExternalScriptLoaded(){}
</script>
Then on your external page:
<script>
try{ ExternalScriptLoaded(); }catch(err){alert('This page was not loaded with ajax because i can't find the function');}
</script>
The alert will trigger if the script can't find the function on your main page.
i.e. call the function after you know the script has finished runnng.
Hope this helped.
Now that I understand how to access both the raw HTML+Javascript (as received by HTTP GET) and the rendered-result of auto-processing of the Javascript upon page load completion, I need to understand how it is being done:
Is there a specific Javascript
function, embedded in the raw HTTP
GET resonse, that the browser looks
for, and when found, it simply calls
it? (in other words, is it the
responsibility of the web page
programmer to instruct the browser
to scan the raw content and
substitute all non-interactive
Javascript to HTML?)
Does the browser analyze the entire
page, looking for certain cues, and
then decides what to convert? If so,
what are these cues and how it is
being done?
Being totally fresh in this subject, it is quite possible that none of the above applies and the trick is done in completely different manner. If this is indeed the case, would you be so kind as to guide me how to re-phrase the question?
The HTML specification defines the circumstances under which Javascript runs. Some javascript it attached to onSOMETHING attributes, and it runs at the defined time. One important example of which is 'onload'. Other Javascript is simply in top-level blocks inside of <script> elements. By spec, the browser runs that whenever it feels like, just in order.
There's no 'conversion' and no 'substitution'. Javascript is a programming language. The browser runs the code. In some cases, the code does interact with the DOM tree to produce displayable contents. In other cases, it does not (e.g. sending information over a connection).
HTML gets loaded sequentially. When a script tag is discovered, the browser executes the script. For example:
<div id="test"></div>
<script type="text/javascript">document.getElementById("test").innerHTML = "Hi there!";</script>
However, if you have the following document
<script type="text/javascript">document.getElementById("test").innerHTML = "Hi there!";</script>
<div id="test"></div>
nothing would happen, because at the time the browser executes the script, the browser hasn't discovered the test div yet.
When a web browser parses an HTML page, if it encounters a <script> element, it stops parsing the HTML, and runs the JavaScript in (or linked to by) the <script> element immediately*.
The JavaScript code can amend the page’s DOM (Document Object Model — the programmatic representation of the HTML that JavaScript can access), and thus change the rendered HTML that’s shown by the browser. (It can also assign functions to built-in event handlers on DOM nodes, so that some JavaScript can be run e.g. when the user clicks on a link, or when the document has finished loading.)
It is thus indeed entirely the responsibility of the web page programmer to do this. Browsers don’t guess what to do with the downloaded JavaScript. They run and obey it.
(* That’s a bit of a simplification: the defer attribute can prevent the script from being run immediately.)
I red your last thread.
Let me tell you this,
A browser has a HTML version of the page and a DOM (Document Object Model) version of it.
Whenever a Javascript changes something, it's changed in the DOM. At first DOM is generated from page HTML,
So Javascript doesn't change page source.
Your question here is totally irrelevant, Since the browser does this operation for loading a page :
HTTP request to recieve data (possibly an HTML document)
Parse the received data (if it is HTML)
Look for other resources in the parsed data (links to other javascript, css, images, etc.)
Download the remaining resources (loop back to step 2)
Generate the DOM, run the CSS and Scripts, show images.
The browser starts running all the javascript from top to bottom of the received data. You can also assign Javascript function to Events of elements on the page, so that when the event is triggered, The javascript function specified is automatically called.
Parsing a HTML and running its javascript has nothing to do with HTTP protocol and can be done solely on your own computer (opening a HTML file on your disk).
The browser parses the HTML code, and upon encountering JavaScript code enclosed in proper <script> tags, it evaluates the encountered JavaScript which can result in document structure and/or content changes that become visible to the user.
Is there a specific Javascript function, embedded in the raw HTTP GET resonse, that the browser looks for, and when found, it simply calls it? (in other words, is it the responsibility of the web page programmer to instruct the browser to scan the raw content and substitute all non-interactive Javascript to HTML?)
No. There are many. See http://dev.opera.com/articles/view/creating-and-modifying-html/
(Actually, you should probably start at http://dev.opera.com/articles/view/1-introduction-to-the-web-standards-cur/#toc )
Does the browser analyzes the entire page, looking for certain cues, and then decides what to convert? If so, what are these cues
<script>
and how it is being done?
DOM
I have read that it is not recommended to instantiate jQuery multiple times in your HTML. This makes perfect sense to me, but:
Isn't Javascript single-threaded anyway? And leaving jQuery behind, how does the browser execute these multiple script tags? In parallel or one after another?
Thanks, Philip
Simple answer:
In a simple scenario (tags are part of original HTML text), the browser definitely executes them one after another.
Detailed discussion with different caveats
JavaScript isn't necessarily single-threaded (it depends on the implementation of your JavaScript engine, e.g. see Web Workers).
BUT, the individual <script> tags are executed sequentially.
For reference, please see JavaScript: The Definitive Guide. Quoting Chapter "12.3. Execution of JavaScript Programs":
JavaScript statements that appear between and tags are executed in order of appearance; when more than one script appears in a file, the scripts are executed in the order in which they appear. If a script calls document.write( ), any text passed to that method is inserted into the document immediately after the closing tag and is parsed by the HTML parser when the script finishes running. The same rules apply to scripts included from separate files with the src attribute.
Please note that the above is only true of "straight up" execution of code in tags. The order can, however, be affected by:
setTimeout() calls (duh)
defer attribute
Dynamic attachement of the <script> tags - see the last section of this answer.
As a caveat, please note that JavaScript code loaded externally via <script src="xxxx" /> would still be executed sequentially, BUT, it is quite possible that the browser would DOWNLOAD the code in parallel - depends on browser implementation (but still schedule the execution of downloaded code snippets in correct order).
This caveat is important in case you want to have some weird hack whereas the URL for the JavaScript source is actually a CGI script which does something and you try to depend on the correct order of downloads for the logic in the script.
Again, it would have no bearing on your browser JS engine's execution order of those script pieces.
However, a far more important caveat is that if you actually attach the <script> tags with external sources dynamically (e.g. via appendChild() call), according to this SO post, as well as the MSDN blog the post was based on, non-IE browsers do NOT guarantee the order of execution! It will depend on which tag's code finished downloading first!
The fewer calls you make that instantiate a jQuery object, the less overhead you have -- but even if you are designing for old browsers running on 2nd generation hardware be wary of micro-optimizations. Profile your application and fix the parts that actually are the bottlenecks.
As for the way browsers handle multiple script tags -- it varies from browser to browser, from version to version, and sometimes even from operating system to operating system. All browsers execute each script tag in document order:
<script src="scripts/some_script.js"></script> <!-- Executed 1st -->
<script src="scripts/some_other_script.js"></script> <!-- Executed 2nd -->
<script>
// Some JavaScript
</script> <!-- Executed 3rd -->
<script>
// Some More JavaScript
</script> <!-- Executed 4th -->
However, other behaviors are not defined and there is variation. For example, Opera (at least on Windows XP for version 10.6) ran each script tag in its own context -- so local variables in the 3rd script block would be out of scope if referred to in the 4th script block.
<script>
var i = 42;
</script>
<script>
alert(i);
// Alerts "undefined" in Opera, but 42 in Firefox.
</script>
The browser executes JavaScript sequentially (the same is true for jQuery since jQuery is just JavaScript).
As for having multiple script tags in HTML, there's no reason why this would be a problem. As Nabab asked, I would be interested in seeing your source for that.
Doesn't the browser compile all the javascript anyway into one "file" during processing. For example, if you had multiple $(document).ready() calls across multiple files, when the browser pre-processes the page, it essentially condenses everything down for execution - and runs it sequentially in the order it was 'seen'.
Yes, we can write any number of tags inside tag. And browser access them in sequential order.
<html>
<body>
<!-- here your code-->
<script></script>
<script></script>
<script></script>
.
.
.
<script></script>
</body>
</html>
I Know, for instance, that when Chrome downloads a Javascript file, it is interpreted and JITed.
My question is, when IE6,7,8, first download a Javascript file, is the entire thing parsed and interpreted?
My understanding was that only top level function signatures and anything executed in the global scope was parsed on load. And then function bodies and the rest were parsed on execution.
If they are fully parsed on load, what do you think the time savings would be on deferring the function bodies to be downloaded and parsed later?
They are fully parsed on load. (IE has to parse the script to know where each function body ends, of course.) In the open-source implementations, every function is compiled to bytecode or even to machine code at the same time, and I imagine IE works the same way.
If you have a page that's actually loading too slowly, and you can defer loading 100K of script that you're probably not going to use, it might help your load times. Or not—see the update below.
(Trivia: JS benchmarks like Sunspider generally do not measure the time it takes to parse and compile the code.)
UPDATE – Since I posted this answer, things have changed! Implementations still parse each script on load at least enough to detect any SyntaxErrors, as required by the standard. But they sometimes defer compiling functions until they are first called.
Because defining a function is actually an operation, yes, your entire javascript file is parsed, and all of the top-level operations are interpreted. The code inside of your functions is not actually executed until it's called, but it is parsed.
for example:
var i=0;
var print = function( a ) {
document.getElementById( 'foo' ).innerHtml = a;
}
Everything gets parsed in the above example, and lines 1 and 2 get executed. However, line 3 doesn't get executed until it's called.
There are little "perceptual games" you can play with your users, like putting the script tags at the bottom of the HTML instead of at the top, so that the browser will render the top of the page before it receives the instructions to download and parse the javascript. You could probably also push your function definitions into a document.onload function, so that they don't get executed until after the whole page is loaded and in memory. However, this could cause a "flash of unstyled content" if your javascript is applying visual styles to things (such as jQuery UI stuff).
Yes, on all browsers the downloading of the resource blocks everything else on the page (CSS downloading, other JS downloading, rendering) if done with a <script> tag.
If you're loading all the javascript at the beginning or throughout your page you will see hiccups as a request is about 50ms and the parsing for a library file or something similar could be more than 100ms. 100ms is used as the standard for which anything greater will be noticed as "lag" by the user.
The time savings may be negligible, but the slight loss of user experience if there are pauses when your page is loading may be significant depending on your situation.
See LABjs' site for a lot of articles and great explanations on the benefits of deferring loading and parsing.
What do you mean by "downloads"? When it's included with tag, or when it's downloaded through XMLHttpRequest?
If you mean the inclusion by script, then IE interpret all js files at once. Otherwise you will be not able to call functions in that file or see syntax error message.
If you mean download by XMLHttpRequest, then you have to evaluate the content of the file yourself.