Celeritas
Celeritas

Reputation: 15043

What order do browsers render webpages and why would script blocking be a concern?

Consider the following scenario:

<h1>Hello!</h1>
<script src="cool1.js"></script>
<script src="cool2.js"></script>
<h2>Goodbye!</h2>
<img src="boat.gif" alt="Big Boat">

When cool1.js is being downloaded does that mean that Hello! has been displayed but Goodbye! will not be displayed until cool1.js downloads AND executes?
When will cool2.js download (I know JavaScript is single threaded so it has to wait for cool1.js to finish executing)? When will boat.gif download and display?

Here the author claims:

The browser can only be executing JavaScript or rendering UI at any particular point in time ... think of what happens as a page downloads to the browser. The page has started to render as it was downloaded, and then a tag is encountered. At that point, the browser can no longer continue rendering because the JavaScript may affect the UI, and so it waits.

I don't get this because couldn't JavaScript modify content that came before it?
For example what if cool1.js changed the contents inside <h1> to say "Good day"?

Upvotes: 2

Views: 1197

Answers (2)

jfriend00
jfriend00

Reputation: 707288

Script block is a concern because it postpones (or delays) the visibility of page elements physically located after the script in your HTML file thus delaying when those later page elements are visible to the viewer and making it take longer to display your whole page.

In this block:

<h1>Hello!</h1>
<script src="cool1.js"></script>
<script src="cool2.js"></script>
<h2>Goodbye!</h2>
<img src="boat.gif" alt="Big Boat">

Here's what you can conclusively say:

  1. Yes, the browser will block further rendering of the page while it downloads and runs an inline script.
  2. The <h1>Hello!</h1> will be in the DOM and available before the cool1.js script runs.
  3. The cool1.js script will run before cool2.js and both will run before the rest of the DOM is available.
  4. The download and execution of both script files will delay the visibility of the rest of the web page that is situated after them. This is why it is recommended to put as much javascript as possible AFTER your content or use some sort of deferred loading so your content can be displayed as fast as possible without waiting for scripts to run.
  5. Javascript cannot modify content in your page before it is displayed. If the script is after the content, then the content may already be displayed before the javascript can modify it. In that case, the script can modify the content, but it may have already been displayed in the pre-modified state. If the script is before the content, then the content is not yet in the DOM for the script to modify. One trick in this regard is for the content to be initially hidden (via inline styles or CSS rules) so the javascript can modify it and then make it visible.
  6. A smart browser will download cool1.js, cool2.js (and maybe even boat.gif too) at the same time subject to the connection limit in the browser. But, cool2.js won't be run until after cool1.js runs and boat.gif won't be put into the DOM until after cool2.js runs.
  7. boat.gif may be downloaded in parallel with other downloads (that's up to the browser), but it will not display until some time after cool2.js has run. Older browsers probably won't even start downloading it until after cool2.js has run.

So, as far as general advice for performance optimizing your site:

  1. Load as many scripts as possible after the content of your page or use defer or async loading on them. This will keep your content from blocking while those scripts are waiting to load and run.
  2. Use common script files across your whole site so that the browser can efficiently cache them.
  3. Combine multiple script files into one larger minimized script file whenever possible because it is faster to download a single script file rather than two script files.

See this answer to a related question for a lot of the details about loading scripts with the async or defer attribute: load and execute order of scripts.

Upvotes: 4

GitaarLAB
GitaarLAB

Reputation: 14645

JFriend00 already has an excelent answer, but I'm leaving my answer to answer your other part of the question: 'why would script blocking be a concern?'

Until the external javascript has downloaded, rendering on the page stalls which could potentially lose you traffic as people give up waiting.

Instead it's sometimes a good idea to load the remote Javascript asynchronously so the page can continue to render and the code is downloaded in the background.

The main point is, you need to think when specific scripts are needed and place/load/execute them accordingly (and async can make this more difficult since you might need to defer the functions in the external file from running until the page has rendered, see this page for examples how to handle this).

Upvotes: 1

Related Questions