Is Javascript parsed/interpreted on load? (IE) - javascript

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.

Related

Why google is using the term "Render-Blocking JavaScript"?

See:
https://developers.google.com/speed/docs/insights/BlockingJS
Google is talking there about "Render-Blocking JavaScript", but in my opinion that term is incorrect, confusing and misleading. It almost looks like "Google" is also not understanding it?
This point is that Javascript execution is always pausing / blocking rendering AND also always pausing / blocking the "HTML parser" (at least in Chrome and Firefox). It's even blocking it in case of an external js file, in combination with an async script tag!
So talking about removing "render-blocking Javascript" by for example using async, implies that there is also non blocking Javascript or that "async Javascript execution" is not blocking rendering, but that's not true!
The correct term would be: "Render-Blocking Download(s)". With async you will avoid that: downloading the js file, will not pause / block rendering. But the execution will still block rendering.
One more example which confirms it looks like Google is not "understanding" it.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test</title>
</head>
<body>
Some HTML line and this is above the fold
<script>
// Synchronous delay of 5 seconds
var timeWhile = new Date().getTime();
while( new Date().getTime() - timeWhile < 5000 );
</script>
</body>
</html>
I tested it in Firefox and Chrome and they are showing (rendering): "Some HTML line and this is above the fold" after 5 seconds and not within 5 seconds!!!! It looks like Google is thinking that in a case like that, the Javascript will not block rendering, but as expected from theory, it will block. Before the js execution will start, all the html is already in the DOM (execept end body / html tag), but rendering is not done yet and will be paused. So if Google would be really aware of this, then Chrome would first finish rendering before starting with the execution of javascript.
If you take the example above and you're using:
<script src="delay.js" async></script>
or
<script src="delay.js"></script>
instead of internal javascript. Then it can also give the same results as the example above. For example:
If the preloader (scanning for files to already download) already would have downloaded "delay.js", before the "HTML parser" is coming at the Javascript part.
Usually external files from Google, Facebook et cetera are already stored in the cache, so there is no download and they just take the file from cache.
In cases like that (and also with async), the result will be the same as the example above (at least in pretty a lot of cases). Because if there is no extra download time, the "Javascript execution" will / can already start, before the preceding html finished rendering.
So in a case like that you could even consider to put "no-cache" / "no-store" on delay.js (or even extra delay), to make your page render more fast. By forcing a download (or extra delay) you will give the browser some extra time to finish rendering of the preceding html, before executing the render blocking Javascript.
So i really don't understand why Google (and others) are using the term "Render-Blocking JavaScript", while from theory and from "real life" examples it looks like it's the wrong term and wrong thinking. I see noone talking about this on the internet, so i don't understand. I know i am f**king intelligent (j/k), but it looks kind of weird to me, to be the only one with the thoughts above.
I work with developers on Chrome, Firefox, Safari and Edge, and I can assure the people working on these aspects of the browser understand the difference between async/defer and neither. You might find others will react more politely to your questions if you ask them politely.
Here's an image from the HTML spec on script loading and execution:
This shows that the blocking happens during fetch if a classic script has neither async or defer. It also shows that execution will always block parsing, or certainly the observable effects of parsing. This is because the DOM and JS run on the same thread.
I tested it in Firefox and Chrome and they are showing (rendering): "Some HTML line and this is above the fold" after 5 seconds and not within 5 seconds!!!!
Browsers may render the line above, but nothing below. Whether the above line renders depends on the timing of the event loop in regards to the screen refresh.
It looks like Google is thinking that in a case like that, the Javascript will not block rendering
I'm struggling to find a reference to this. You linked to my article in an email you sent me, which specifically talks about rendering being blocked during fetching.
In cases like that (and also with async), the result will be the same
That isn't guaranteed by the spec. You're relying on retrieval from the cache being instant, which may not be the case.
in a case like that you could even consider to put "no-cache" / "no-store" on delay.js (or even extra delay), to make your page render more fast. By forcing a download (or extra delay) you will give the browser some extra time to finish rendering of the preceding html, before executing the render blocking Javascript.
Why not use defer in this case? It achieves the same without the bandwidth penalty and unpredictability.
Maarten B, I did test you code and you are correct indeed. Whether you use async, defer or whatever, the lines above the inline JavaScript are not beeing rendered. The information in the documentation of Google is therefore incorrect.

Difference in performance and memory footprint between referencing a Javascript using src or directly injecting it in the HEAD

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

Does inline javascript block the UI thread?

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..

IE 7 & 8 javascript file undesirably caching with require.js

I have a page javascript page.js being loaded with require.js. The call to the page.js is placed on the bottom of the page after the calls to require.js and is as follows:
<script>
require(["page"]);
</script>
Functions inside the page.js simply do not execute each time the page is accessed.
To be clear, an alert('hello'); in the middle of page.js will be alerted most but not all of the times. I'm pretty sure this is not an existing IE issue, and that a simple alert will always execute provided there are no other JS errors.
95% of the time the page and it's corresponding functions execute, about 5% of the time the IE browsers are not reexecuting the contents of the page.js.
I don't think this is an inherent IE issue, but rather require.js is stumbling over related aggressive caching issues found in IE.
Edits:
Just to clarify, the page.js file is visible in the f12 dom load when the error occurs. The page is properly cached. The issue is that the cached code file is not re run!
For instance the alert in this file is not executed!
I'm not sure about the internals of require.js but I suppose they do xhr for the resources and eval it. It seems the xhr completes and loads into the dom, but the eval isn't working correctly. (This is of course speculation, as I don't know enough require.js internals).
The only way i know to prevent caching your js files is to add a random string to the end :
example :
<script src="http://www.mydomaine.com/myjsfile.js?t=123456"></script>
generate the "t" parameter content randomly using an md5 hash or wathever, this makes browsers believe that it's a different file each time.
There problem may not be due to caching. Caching is basically controlled on the server-side, so if you do not want a file cached, you have the server setting the cache-control headers to do that. Caching does not affect if a javascript file is "executed" or not, it only affects where the browser gets data from when trying resolve a given resource. Normally, you want .js files to be cached for performance reasons.
In your case, caching may not be the real problem. When using dynamic javascript source loaders (libraries like dojo support this), it may best that the file you load is wrapped in the following:
(function(){
// Main code here...
})();
This defines an anonymous function, and then executes it right away. This gives the following advantages:
Creates a closure so you can declare variables that are only visible in the scope of your file.
Ensure that any direct executable statements are executed.
Note, I'm not familar with require.js, so there is a possibility it can play a role in your problem. Also, you did not provide the file you are loading via require, which it may have a bug that is causing the inconsistency you are encountering.
Conclusion:
IE (where it was mostly occurring) was kind of swallowing up the error, when we were able to reproduce it in Chrome, we found an error indicating that one of our global funcs wasn't yet loaded because the global funcs file wasn't added to the require list. Unfortunately, we're not using require.js's compile + optimization which may or may not have barfed without an IMPLICIT listing of the globals.js as a dependency.
I guess the take home is make sure any functions called are themselves defined in a dependency implicitly listed in the require block!

putting jquery and javascript into external file

A lot of my pages have amll bits of jquery.
Im thinking of putting them into one external file with one $(document).ready(function() {
and everything in there.
is this a good/bad idea?
will each page be slower overall if there is more code to execute even if its not relevant to the page? i imagine each line of code in the external script gets executed when the dom is ready..? or is my understanding wrong?
will each page be slower overall if there is more code to execute even if its not relvamnt to the page?
The external script file may have some overheads for loading, but if you use the script on any number of pages more than one, external is a good idea; it'll be cached and be instant.
i imagine each line of code in the external script gets executed when the dom is ready..? or is my understanding wrong?
Yes. If you wrap your code in a function as an argument to $(document).ready() it gets executed on DOMContentLoaded.
If you put all your bits of JS into one page - without calling them as functions- then, yes, they will get executed everytime you include them. It would be better to put the common functions into an external scripts and keep it there. This will increase your code reuse as well as speed up page load because your JS will be cached.

Categories

Resources