In countless places online we have seen the recommendation to include CSS prior to JavaScript.

The reasoning is generally, of this form:

use the following page to test

[pastacode lang=”markup” manual=”%3C!DOCTYPE%20html%3E%20%0A%3Chtml%3E%20%0A%3Chead%3E%20%0A%3Ctitle%3Etest%3C%2Ftitle%3E%0A%20%3Cscript%20type%3D’text%2Fjavascript’%3E%20var%20startTime%20%3D%20new%20Date()%3B%20%3C%2Fscript%3E%20%0A%3Clink%20href%3D%22http%3A%2F%2F10.0.0.50%3A8081%2Ftest.css%3Fdelay%3D500%22%20type%3D%22text%2Fcss%22%20rel%3D%22stylesheet%22%3E%20%0A%3Cscript%20type%3D%22text%2Fjavascript%22%20src%3D%22http%3A%2F%2F10.0.0.50%3A8081%2Ftest2.js%3Fdelay%3D400%26amp%3Bjsdelay%3D1000%22%3E%3C%2Fscript%3E%20%3C%2Fhead%3E%0A%20%3Cbody%3E%20%0A%3Cp%3E%20Elapsed%20time%20is%3A%0A%20%3Cscript%20type%3D’text%2Fjavascript’%3E%20document.write(new%20Date()%20-%20startTime)%3B%20%3C%2Fscript%3E%20%3C%2Fp%3E%20%3C%2Fbody%3E%20%3C%2Fhtml%3E%20%0A” message=”Html Code” highlight=”” provider=”manual”/] [ad type=”banner”]

When we include the CSS first, the page takes 1.5 seconds to render:

When I include the JavaScript first, the page takes 1.4 seconds to render:

[ad type=”banner”]

  • What appears to be happening is that the JavaScript interpreter refuses to start until all the CSS is downloaded. So, it seems that having JavaScript includes first is more efficient as the JavaScript thread gets more run time.
  • Is the recommendation to place CSS includes prior to JavaScript includes not correct?

  • We have always put the CSS <link href=”…”>s before the JS <script src=”…”>s because it’s high time we do some actual research!
  • Made sure there was no HTTP caching so the browser would have to do a full download each time a page is loaded.
  • To simulate reality, we included jQuery and the H5BP CSS (so there’s a decent amount of script/CSS to parse)
  • Set up two pages – one with CSS before script, one with CSS after script.
  • Recorded how long it took for the external script in the <head> to execute
  • Recorded how long it took for the inline script in the <body> to execute, which is analogous to DOMReady.
  • Delayed sending CSS and/or script to the browser by 500ms.
  • Ran the test 20 times in the 3 major browsers.

There are two main reasons to put CSS before JavaScript.

  • Old browsers (Internet Explorer 6-7, Firefox 2, etc.) would block all subsequent downloads when they started downloading a script.
  • So if you have a.js followed by b.css they get downloaded sequentially: first a then b. If you have b.css followed by a.js they get downloaded in parallel so the page loads more quickly.
  • Nothing is rendered until all stylesheets are downloaded – this is true in all browsers. Scripts are different – they block rendering of all DOM elements that are below the script tag in the page.
  • If you put your scripts in the HEAD then it means the entire page is blocked from rendering until all stylesheets and all scripts are downloaded.
  • While it makes sense to block all rendering for stylesheets (so you get the correct styling the first time and avoid the flash of unstyled content FOUC), it doesn’t make sense to block rendering of the entire page for scripts.
  • Often scripts don’t affect any DOM elements or just a portion of DOM elements. It’s best to load scripts as low in the page as possible, or even better load them asynchronously.

During the loading of your website, there are two scenarios that you would see:

CASE 1: white screen > unstyled website > styled website > interaction > styled and interactive website

CASE 2: white screen > unstyled website > interaction > styled website > styled and interactive website

“When using scripts that rely on the value of CSS style properties, it’s important to reference external stylesheets or embed style elements before referencing the scripts”.

When the files are loaded in the wrong order (first JS, then CSS), any Javascript code relying on properties set in CSS files (for example the width or height of a div) won’t be loaded correctly. It seems that with the wrong loading order, the correct properties are ‘sometimes’ known to Javascript (perhaps this is caused by a race condition?). This effect seems bigger or smaller depending on the browser used.

  • There are several things to consider here, and the relevance of these recommendations almost always become rules when you venture into high-caliber web development.
  • The purpose of the “put stylesheets at the top and scripts at the bottom” rule is that, in general, it’s the best way to achieve optimal progressive rendering, which is critical to the user experience.
  • All else aside: assuming your test is valid, and you really are producing results contrary to the popular rules.
  • Every website (and everything it takes to make the whole thing appear on a user’s screen) is different and the Internet is constantly evolving.

  • We include CSS files before Javascript for a different reason.
  • If Javascript needs to do dynamic sizing of some page element (for those corner cases where CSS is really a main in the back) then loading the CSS after the JS is russing can lead to race conditions, where the element
  • is resized before CSS styles are applied and thus looks weird when the styles finally kick in.
    If load the CSS beforehand we can guarantee that things run in the intended order and that the final layout is what we want it to be.
[ad type=”banner”]

The css will download parallel but js cant. Consider for the same case,

Instead of having single css, take 2 or 3 css files and try it out these ways,

1) css..css..js
2) css..js..css
3) js..css..css

css..css..js will give better result than all others

We have to keep in mind that new browsers have worked on their Javascript engines, their parsers and so on, optimizing common code and markup problems in a way that problems experienced in ancient browsers such as <=IE8 are no longer relevant, not only with regards to markup but also to use of JavaScript variables, element selectors etc.

We can see in the not so distant future a situation where technology has reached a point where performance is not really an issue anymore.

Categorized in: