0

If I have an HTML page that includes some JavaScript, for example:

<script type="text/javascript" src="http://example.com/code.js" async></script>

And I want to add some CSS, which of the following 2 options is faster, performance-wise?

Option 1

(More "Network Heavy") Including the CSS in a separate inline tag, for example:

<link rel="stylesheet" type="text/css" href="http://www.example.com/style.css">

OR

Option 2

(More "JavaScript Execution Heavy", since it requires DOM manipulation) injecting the CSS into the DOM from inside the included JavaScript file, for example (taken from: https://stackoverflow.com/a/707580/1785003]1):

var css = document.createElement("style");
var css = "text/css";
css.innerHTML = "strong { color: red }";
document.body.appendChild(css);

The 2nd option removes a network request from the page, but requires DOM manipulation, which might be costly in Mobile Device browsers.

So which is better?

Community
  • 1
  • 1
BlueYoshi
  • 1,534
  • 12
  • 18
  • Remember that the network request will happen only once if caching is configured properly. Also, a proper `` tag allows for pre-loading magic etc. – Pekka Mar 14 '13 at 09:41
  • 1
    Option 3, of course, is to just put a `style` element in the page directly. Why would you need to add it via JavaScript?! – T.J. Crowder Mar 14 '13 at 09:44
  • @T.J.Crowder Thought about that, but it's not an option for the current scenario - my code is added by 1 or 2 includes by various other websites. – BlueYoshi Mar 14 '13 at 09:51
  • 1
    @Yosi: That doesn't make any sense. You're saying that your "code is added" and that you can have that include a `script` element, or you can have that include a `link` element. But you can't have it include a `style` element? Why not? – T.J. Crowder Mar 14 '13 at 10:09
  • 1
    @T.J.Crowder Assume that my code is like an "external widget", so I have no server-side control, and no control over the page's static HTML. All I have is either one "include" line for my JavaScript file OR one "include" for my JavaScript and one "include" for my CSS. – BlueYoshi Mar 14 '13 at 11:18
  • 1
    @Yosi: Okay, that makes sense. I'd say I'm with Daveo on this: Putting the CSS in the JavaScript is a maintenance problem waiting to happen. Don't do it until/unless you find a specific, painful performance hit and you can identify that putting the CSS in the JavaScript fixes that. – T.J. Crowder Mar 14 '13 at 11:32

3 Answers3

1

I do not believe there is much of a difference between a mobile device and regular browser in the way they load and cache pages so I would treat them the same.

Having CSS in your JavaScript is going to be a maintenance nightmare. Probably not worth any tiny (if any) optimisation gain. As Pekka pointed out after initial load it will cached.

You will be better off targeting other performance optimisations first. Like Minify CSS and javascripts, CSS sprites etc . Use a tool such as yslow to help show where performance optimisations can be made.

Also most browsers can make at least 4 concurrent request to the same host so that the CSS and Javascript , HTML can all be downloaded at the same time. See here

Daveo
  • 19,018
  • 10
  • 48
  • 71
1

Answering from Performance POV:

Using CSS is a better option.

Reason
Performance is not just measured in network bandwidth consumption. JS blocks the rendering of the page till they're completely downloaded.

(Note: html 5 now suports

<script type="text/javascript" src="http://example.com/code.js" async></script>

which frees loading of rest of your markup in parallel.)

Once css is fetched for first time, then it is neither downloaded nor executed (vs javascript). This is delight for returning users.

Solution
Use the external css and keep it at the top of your semantics (in <head> section, preferably). Use external js and keep it at the bottom of the page (near the </body> tag)

Background:
Have worked with Yahoo! and adhered to their Best Frontend practices.

  • Put Stylesheets at the Top
  • Put Scripts at the Bottom
Vishal Verma
  • 962
  • 8
  • 18
0

The CSS file will definently render faster, once it's downloaded and processed, since browser are optimised for this. Applying via JS means that you need to wait for the document to load, then seek elements, apply styling, and then allow the browser to do its magic.

In my experience, adding a CSS file for anything more than dynamic behavior by far outweights any "speed" decrease due to maintainability (how easy it is to change something) and because you can actually restyle your page without editing the code part, which can break things (if for instance you change the JS generating the styles and forget a quote, you break the page, and lose all JS for that page).

The only situation where styling via JS is ok for non-dynamic behavior, is when its a few lines all in all, and even then I'm cautious.

Nick Andriopoulos
  • 10,313
  • 6
  • 32
  • 56
  • *"...once it's downloaded and processed..."* That's a **big** caveat on mobile devices. *"Applying via JS means that you need to wait for the document to load, then seek elements, apply styling, and then allow the browser to do its magic."* No, the question is about adding a `style` element, not setting the style of individual elements. – T.J. Crowder Mar 14 '13 at 10:07
  • Adding a `style` element basically defers the weight (sizewise) of the CSS to JS, increasing that payload and limiting the effect of concurrent (HTTP 1.1) file download. That again will be slower. Is there something I don't understand here? – Nick Andriopoulos Mar 14 '13 at 10:10
  • @ hexblot: I don't think the OP should use *either* of the options he/she is discussing. But he said that the page *already* has a `script` being applied, and asked whether to add another HTTP request (a CSS file) or just put some code in that script to add a `style` element on the fly. HTTP requests are very expensive on mobile devices due to latency, thus minimizing them is paramount. So if the script is already there, adding the CSS text to it avoids a request. (But again, I think the OP is missing Option 3.) – T.J. Crowder Mar 14 '13 at 10:14
  • @T.J.Crowder: Option 3 would be better (having ESI/SSI to do it from a CSS file is the best of both worlds). But the maintainability of having anb external CSS file far outweights the latency of including a single CSS file, even on mobile. You may want to optimise that single CSS file to bits (only have rules needed for each page) to keep it small, but still - server side needs to have a CSS file. If you keep everything in one place, it's simply bad, non-maintainable practice, no matter the target platform. – Nick Andriopoulos Mar 14 '13 at 10:21