1

Let's say I'm building a static 10-page website for a client, and there's only a few lines of JavaScript for the whole site (less than 1KB). In this situation I'd guess that it's best (for performance) to put the <1KB of JavaScript code inline between script tags on every page, rather than in an external .js file. The extra bandwidth consumption (when moving between pages) is probably worth it for removing a whole HTTP request.

At the other end of the spectrum, if I had 200KB of JavaScript on the same website, then I'd definitely put this in a separate file to reduce bandwidth when moving between pages on the site.

But I've no idea where the 'cut-off point' should be. If I have 5KB of JS, should I just put this inline in my HTML? What about 10KB? 20KB?

Obviously the 'cut-off point' is going to depend on the situation, e.g. it might be different for mobile sites. But if anyone has any general pointers that would help guide this decision, then I'd like to hear them.

(NB: I'm interested only in performance here, not maintainability etc. I can keep my code in separate files but use some kind of build process or serverside middleware to automatically inline it, so maintainability will not be an issue.)

(Bonus points: please let me know if all the considerations are exactly the same with inline vs. external CSS.)

callum
  • 34,206
  • 35
  • 106
  • 163
  • 9
    I would say *always* put Javascript in a separate file. *No exceptions*, at all. Ever. – Andrew Barber Apr 11 '12 at 18:30
  • 8
    I think even for the 1KB Javascript, it's preferrable to link to it, because it only has to be fetched exactly *once*. If you put it inside your HTML, it has to fetched for every request – Niklas B. Apr 11 '12 at 18:30
  • 1
    @NiklasB. When it's inline, it's not really *fetched* at all; there's no extra HTTP request. It just comes in with the HTML. Yes it increases that HTML size by a little, but my point is, perhaps that's sometimes worth it, to avoid a whole extra HTTP round trip? Google search for example is incredibly fast loading, and uses a lot of inline JavaScript to avoid extra requests. – callum Apr 12 '12 at 09:39
  • @AndrewBarber - wow, really, that extreme? Can you tell me why? And can you tell me why Google uses loads of inline JavaScript? – callum Apr 12 '12 at 09:40
  • 1
    The advice to always put it in a separate file isn't right. HTTP requests aren't 'free', they come with an overhead, particularly if it's one of the first requests on the page and subject to TCP slow-start. The overhead gets larger as latency increases. – Andy Davies Apr 12 '12 at 10:43

3 Answers3

3

I'm strictly talking about performance here, more as a thought experiment (and please excuse the lack of experimental rigor).

If you're inlining the javascript, yes you do save time in the fact that everything is done in one http request. However, you should factor in the time it takes for a server to dynamically generate the webpage that you need (SSL also adds time to this).

Best case

If you can create a build that generates minified javascript and injects it into an html page, combined with gzip compression, you should result in a much lower bandwidth. The more text you stick in the compression, the bigger your payoff compared to individually gzipping per request. Ultimately, this means if you can have it load a single html page statically with all the javascript/css inline, this means it will definitely be faster.

Normal case (with dynamic html and shared js libraries)

A small sample of some stackoverflow posts and how they affect my own bandwidth:

304ms 9.67KB
204ms 11.28KB
344ms 17.93KB
290ms 17.19KB
210ms 16.79KB
591ms 37.20KB
229ms 30.55KB

Judging from this, it seems like the overhead incurred (disregarding filesize) is around 150ms for each http connection - perhaps in the worst case. Now, the question is, how big does the text (javascript in your case) have to be for your bandwidth to incur 150ms. According to this article (http://www.telecompetitor.com/akamai-average-u-s-broadband-connection-speed-is-now-5-3-mbps/), for broadband users, we are working with an average of 5.3 mbps (which is .6625 MB/s or 678.4 KB/s or .6784 KB/ms). This means that for the average broadband user, you will need roughly 100KB download of gzipped+minified javascript for it to equal.

Please adjust the parameters yourself to see what this may mean for your audience. This number, whatever you calculate it to be, is the point at which you may be better off serving it inline (through server-generated response) versus fetching it/caching it externally.

All in all, I don't think that for performance reasons, this is a bottleneck at all. The size of compressed + minified javascript is usually negligible and it has to be on orders of unmaintainable magnitude that it would matter.

badunk
  • 4,310
  • 5
  • 27
  • 47
0

The cutoff point is 0KB -- the answer to "When is a JavaScript small enough to be worth inlining" is "never".

Aside from the maintainability issues, which you say you don't want to consider, it's better for performance anyway. Yes, you have one extra HTTP request the first time you reference the .js file, but after that it's cached so your overall traffic/bandwidth decreases over time.

The same is true for CSS files.

Making the page heavier with inline JS or CSS is more costly than the extra request for the initial fetches of the files (unless you're serving completely static .html where the whole page is cached for a long time)

Stephen P
  • 14,422
  • 2
  • 43
  • 67
  • Its gotta be more than 0, otherwise the rule for optimizing javascript would be to infinitely add arbitrary javascript! ;) – badunk Apr 11 '12 at 21:12
  • 1
    "inline JS or CSS is more costly than the extra request for the initial fetches of the files" - this isn't necessarily true, the overhead of the request for small files will outweigh the 'cost' of including it in the document. This is particularly true for early page requests that have to go through the TCP slow-start phase. – Andy Davies Apr 12 '12 at 10:02
  • 1
    Also the higher the latency the worse it gets - it's why sites like the mobile version bing.com inline the CSS & JS and then cache it in localStorage – Andy Davies Apr 12 '12 at 10:04
  • @AndyDavies - I know you're correct, I wouldn't dispute the start-up or latency issues. Maybe I should amend my answer to say this is **my** rule, because in real-world measurement, on the things I've worked on, the html, css, and js are downloaded in parallel with multiple browser connections, and the benefit of being cached in the browser easily outweighed connection overhead. – Stephen P Apr 12 '12 at 19:39
  • Actually this brings up a good point - I believe there is a max of 2 downloads in parallel at any one time according to the http spec? I forgot where I read that.. – badunk Apr 14 '12 at 09:33
  • @badunk - I don't know offhand if the spec mentions it, but browsers used to allow configuration of that and came set to **4** parallel connections out of the box. I believe they are generally set up to use 2 connections nowdays, and I haven't looked to see if they are still configurable. In any case, making users change that wouldn't be acceptable anyway, although it might be something a corporate deployment configuration might look into. – Stephen P Apr 16 '12 at 20:21
  • Just to add to that, a quick google search led to this: http://www.mydigitallife.info/tweak-increase-or-change-maximum-simultaneous-http-and-downloads-connections-to-web-server/. According to him, the max of 2 concurrent downloads is made by the http 1.1 spec, although the browsers have different self-imposed limits (for example: http://stackoverflow.com/questions/5751515/official-references-for-default-values-of-concurrent-http-1-1-connections-per-se) – badunk Apr 18 '12 at 16:58
  • @badunk - thanks for the links. The spec uses a `SHOULD` for the browser's two connection limit (last paragraph of 8.1.4), and as the SO question and browserscope.org (linked in a comment to that question) both show, browsers now more commonly use four to six connections, with a few lower or higher. These are also *persistent* connections, which mitigates the TCP startup that Andy Davies mentions (and, I think, why I was downvoted). I keep things separate as I say in this answer, and it works well for me *in the real world*. – Stephen P Apr 18 '12 at 17:51
0

Short answer: it depends!

Assuming:

  • You would not inline the script by actually copy-and-pasting it into every HTML page
  • A separate file would be cached properly

Do the numbers. Come up with a rough estimate for how much extra traffic would be generated by the extra HTML, in proportion to the rest of the traffic, and then decide if you think that's an acceptable compromise.

If it's 1% it's probably not worth worrying about. But if it's 50% then you can halve your traffic by putting the script in a separate file.

Michael Slade
  • 13,802
  • 2
  • 39
  • 44