AFAIK, each web page is created in a two stage process: Parsing and rendering. In parsing, markup (Say HTML) is taken as is, or created from a server-side programming language like PHP,

In the rendering, the style (say CSS), is added upon the parsed structures.

Yet I don't know where does JavaScript come, in parsing or rendering:

Is JavaScript added and executed in rendering or parsing?

  • You're forgetting an essential step here. The request is made to the server, and the server outputs or generates the actual html markdown. Whatever language used to do this (PHP, JSP, etc.) is not relevant in terms of the client. The client program (usually a browser) parses the entire document and before rendering, already loads or downloads any missing css, javascript, images, etc. If the javascript is written plainly on the page, then it is simply parsed (no external files to download), otherwise it must ask the server also for the script to download. – Neil Apr 17 at 5:47

It's a bit more complicated, as JavaScript execution is interleaved with the normal lifecycle of the page.

First, the browser must parse the HTML code into the Document Object Model. When the parser encounters a script tag, the script is immediately parsed and executed. The script can modify the HTML code via document.write().

The browser will immediately try to render the DOM, even if the HTML code has not yet been fully parsed, for example if the full code hasn't yet been received. The browser will update the rendering if the DOM changes or as style information becomes available, for example when the correct font is loaded.

Unless proper care is taken, the user experience can be quite janky. Synchronous JavaScript is particularly problematic because its execution blocks further parsing – which might discover other resources that could have been loaded in parallel. So there are a couple of techniques to prevent blocking:

  • use the async attribute for script tags so that the browser doesn't have to block until the script has been loaded & executed
  • link and preload relevant resources as early as possible so that they can be downloaded in parallel
  • avoid document.write(), instead perform DOM manipulation once the DOM is ready
  • defer non-critical JS code until after the DOM is ready
  • ideally, remove any JS code from the critical path, i.e. do not rely on client-side DOM manipulation. That means no React. Instead, use server-side templating. This may not be feasible for very dynamic applications like SPAs.

A note on terminology: “server side rendering” does not mean rendering a DOM with CSS, but serialising a DOM into HTML. So this is more like traditional template engines that are executed on the server, for example as a PHP page. For the client it is irrelevant how HTML is generated: they cannot tell the difference between static HTML files and dynamically rendered templates. In the end the browser just receives HTML code via HTTP which the browser has to parse & render.

  • Thanks amon. Please avoid this comment if you think it's unrelated (I think it will help me to make sure I understand but if you think I should ask a new question I will do so): If Async JS redunds the need to move sync JS to <footer> to prevent "blocking" (waiting for each JS resource in parsing) AND actually takes JS out of parsing to load it only in Rendering in a "First In First Out" way, why not Always use async and be done with it? – JohnDoea Apr 17 at 8:40
  • "its execution blocks further parsing" - usually the browser will keep parsing the data (and even recomputing CSS) in parallel with Javascript execution. It can't update the DOM from under Javascript's nose, but it can prepare the DOM resultant from the parsing and put it in place once Javascript is done running. It only has to discard that data if the Javascript pulls off some document.write type of nonsense. Best case, the Javascript merely sets up a ready handler and stops, in which case the rendering only pauses for the time it takes to retrieve the script from cache. – John Dvorak Apr 17 at 9:58
  • Not sure about the "don't modify DOM client-side" bit. The main bottleneck, as per my guess, is the network response time. GZip is really good at compressing HTML, but there may still be some savings. How much time is lost by having to render CSS after Javascript runs I'm not sure, but CPUs are getting fast these days... – John Dvorak Apr 17 at 10:04
  • Also, if you do server-side rendering on a server that's low on CPU resources (CPU hours cost hosting money), the time to do the rendering will become even more significant than the network time. And of course, all of that is moot if the main bottleneck is that it takes the database five seconds to answer the simplest of queries. I'm looking at you, Azure. – John Dvorak Apr 17 at 10:07
  • @JohnDvorak You do have some valid points: JS execution is not the problem, the problem is delayed discovery of resources that must be loaded. I don't quite buy the CPU resource argument though: if server resources were so precious we'd write backends in Rust not Ruby. Templates are generally not the problem. – amon Apr 17 at 10:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.