2

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?

tim peterson
  • 23,653
  • 59
  • 177
  • 299
  • 4
    alert() will block things until it's acknowledge, regardless of where you put it. – Marc B Sep 22 '12 at 16:34
  • ok, how about if i just make some objects or do some other function calls instead of alerting something? Perhaps you can answer the question by stating what blocks and what doesn't? – tim peterson Sep 22 '12 at 16:36
  • 1
    Both inline JS and `src` will block UI thread as JS is executed when encountered AFAIK. Try echoing a JS file in PHP with 5 secs sleep time in the head, the page won't render until it loads the script. – Fabrício Matté Sep 22 '12 at 16:38
  • @FabrícioMatté, thanks that's very helpful, what's AFAIK? – tim peterson Sep 22 '12 at 16:42
  • As far as I know. I have some test suits and discussed it in SO's JS chat not long ago. – Fabrício Matté Sep 22 '12 at 16:43

3 Answers3

6

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.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • 1
    And the deferred load can be achieved with HTML5's `async` attribute or by dynamically appending a script element to the end of the body tag. – Fabrício Matté Sep 22 '12 at 16:44
  • @FabrícioMatté actually it's the `defer` attribute. – Alnitak Sep 22 '12 at 16:45
  • what's the difference between the `defer` and the `async` attribute? I'm having trouble understanding cases in which I'd use either. – tim peterson Sep 22 '12 at 16:46
  • 1
    You forgot to mention that those attributes do not apply to inline scripts – Bergi Sep 22 '12 at 16:46
  • Oh yes my bad. @timpeterson `defer` will load scripts asynchronously but are warranted to execute in the order they are in the page; `async` will execute at the first opportunity it has once the script is loaded. – Fabrício Matté Sep 22 '12 at 16:48
  • @Bergi, then how do you defer inline scripts such that they don't block? – tim peterson Sep 22 '12 at 16:48
  • Why would you want to do that - they don't do any heavy operations like loading a resource (blocking, as described in your article)? And `alerts` are always blocking ;-) – Bergi Sep 22 '12 at 16:51
  • 3
    @FabrícioMatté I hadn't realised that there was now `async` as well as `defer` - I've updated. – Alnitak Sep 22 '12 at 16:51
  • Yes, but you're right, `defer` is a better option when you have a script that relies on another - e.g. loading the jQuery lib before a script that utilizes jQuery methods. @timpeterson if you don't want blocking UI, move your scripts to the bottom of the `body` tag, by then your page will be fully rendered already. – Fabrício Matté Sep 22 '12 at 16:54
  • @Bergi, sorry the `alert()` was a bad example. What about declaring objects, for example, ones rendered server side using PHP? Please see my updated question. – tim peterson Sep 22 '12 at 16:56
  • 1
    PHP won't affect scripts in any way. Your browser will only see the echoed HTML and JS, and parse it into the DOM tree. Scripts are executed when found, that means it'll "block" the UI thread. However, if you're just creating an object, the block will last no more than a fraction of millisecond (apart from the load time). If you want unobtrusive JS, move your JS to the bottom of the `body` tag which is where they should be. – Fabrício Matté Sep 22 '12 at 17:01
2

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.

  1. Opera is special, but we'll ignore that.
  2. Or entire browser, depending
Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74
  • I don't think Opera is such a special case, as it doesn't really do the substantial things different. Synchronous WebWorker events are not a part of this question :-) – Bergi Sep 22 '12 at 16:59
  • @Bergi -- Opera doesn't freeze the UI like browsers do. In fact, under Opera, you can see some DOM operations happening in real time as they occur. The original question was unclear which type of blocking the OP was asking about. – Jeremy J Starcher Sep 22 '12 at 17:04
0

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

Miro Markaravanes
  • 3,285
  • 25
  • 32
  • perhaps you can expand on your answer to clarify what blocks vs. what doesn't block? Does simply declaring objects block? Like this-> `` – tim peterson Sep 22 '12 at 16:37