I am trying to improve the performance of a web application. I have metrics that I can use to optimize the time taken to return the main HTML page, but I'm concerned about the external CSS and JavaScript files that are included from these HTML pages. These are served statically, with HTTP Expires headers, but are shared between all the pages of the application.
I'm concerned that the browser has to parse these CSS and JavaScript files for each page that is displayed and so having all the CSS and JavaScript for the site shared into common files will negatively affect performance. Should I be trying to split out these files so I link from each page to only the CSS and JavaScript needed for that page, or would I get little return for my efforts?
Are there any tools that could help me generate metrics for this?
Context: While it's true that HTTP overhead is more significant than parsing JS and CSS, ignoring the impact of parsing on browser performance (even if you have less than a meg of JS) is a good way to get yourself in trouble.
YSlow, Fiddler, and Firebug are not the best tools to monitor parsing speed. Unless they've been updated very recently, they don't separate the amount of time required to fetch JS over HTTP or load from cache versus the amount of time spent parsing the actual JS payload.
Parse speed is slightly difficult to measure, but we've chased this metric a number of times on projects I've worked on and the impact on pageloads were significant even with ~500k of JS. Obviously the older browsers suffer the most...hopefully Chrome, TraceMonkey and the like help resolve this situation.
Suggestion: Depending on the type of traffic you have at your site, it may be well worth your while to split up your JS payload so some large chunks of JS that will never be used on a the most popular pages are never sent down to the client. Of course, this means that when a new client hits a page where this JS is needed, you'll have to send it over the wire.
However, it may well be the case that, say, 50% of your JS is never needed by 80% of your users due to your traffic patterns. If this is so, you should definitely user smaller, packaged JS payloads only on pages where the JS is necessary. Otherwise 80% of your users will suffer unnecessary JS parsing penalties on every single pageload.
Bottom Line: It's difficult to find the proper balance of JS caching and smaller, packaged payloads, but depending on your traffic pattern it's definitely well worth considering a technique other than smashing all of your JS into every single pageload.
I believe YSlow does, but be aware that unless all requests are over a loopback connection you shouldn't worry. The HTTP overhead of split-up files will impact performance far more than parsing, unless your CSS/JS files exceed several megabytes.
To add to kamen's great answer, I would say that on some browsers, the parse time for larger js resources grows non-linearly. That is, a 1 meg JS file will take longer to parse than two 500k files. So if a lot of your traffic is people who are likely to have your JS cached (return visitors), and all your JS files are cache-stable, it may make sense to break them up even if you end up loading all of them on every pageview.
Related
I don't know much about JS parsing or performance.
But I would like to know if there is a performance difference when the browser parses a large file, vs smaller ones with the same total size.
What parses faster:
10kb vs. (2 x 5kb)
Does it matter? Or is it negligible? What if we compare:
1mb vs. (1000 x 1kb)
Note1: This is about browsers parsing JS.
Note2: I'm assuming it's all the same JS code. I mean, either in a single file, or split across multiple smaller files, the parsed code should be the same.
(V8 developer here.)
For parsing speed, the overall amount of script matters, not the organization into files.
That said, there could be secondary effects, which could have more impact on overall perceived page load performance than raw parsing speed. As Ashok's answer points out, the downloading is part of the picture, where historically many small resources were at a disadvantage, which as you point out should be addressed by HTTP2. On the flip side, a few resources might get a speedup thanks to concurrent connections, compared to a single larger chunk.
Another effect worth considering is caching. If you have one part of your code that changes rarely (e.g. a third-party library, which you only update every few months) and another part that changes a lot (e.g. your own code, where you deploy new versions every other day), then it makes sense to split the script files along this line, so that the browser can cache the parts that don't change. That would at least avoid the download of the part that hasn't changed; some browsers might even be able to cache the result of parsing/compiling the code, which would save even more work.
The applicable rules of thumb are:
(1) Do what makes sense for your case (i.e. what's most convenient); or at least start with that and see if it works well enough. Premature optimization (i.e.: making things more complicated in the hope of enabling more speed, without having verified whether that's actually necessary or helpful) is usually a bad idea.
(2) Measure any alternatives yourself, with a test that's as close as possible to your real situation. For example, apply a realistic split to your actual sources (maybe in a handful of chunks? or combine them into one if splitting was what you did before) and test that, rather than generating thousands of files with dummy content. If you can't measure a difference, then there is no difference that matters! And if you can measure a difference, then you have your answer :-)
Speed-wise, a single JS file is always better than multiple JS files as browser would be making fewer network requests. Also, to fetch each JS file, the browser would first open an HTTP request connection, perform handshake and then make the data (JS file) transfer.
Due to this, the multiple JS files makes the content load slower.
But again it depends on what code does the JS file holds. For more detailed info please have a look at One big javascript file or multiple smaller files?
I'm working on improving the page performance of my company's intranet page. We're looking to (dynamically) combine our javascript files as well as cache them for 30+ days. The page launches on login for everyone.
One of my coworkers asked if it's worth the time to combine the JS files if we're already caching them for a month. He's hesitant to do both because the combining tool is server side and doesn't run on our desktop, requiring a somewhat hacky workaround.
I've been doing some research and most of the recommendations for performance I've seen are for external sites. Since we're in a closed system it would seem like we wouldn't get much benefit from combining the files once everyone's cache is primed. What would combining the files buy us that aggressive caching wouldn't?
We're on IE8 if that makes any difference.
The most notable impact with having multiple JavaScript files is the time required to render the page. Each script tag is processed separately and adds time to the overall render process.
A pretty good answer can be found here # multiple versus single script tags
If we are talking a large number of scripts then you may see an improvement in render time; if it is just two or three files then it likely won't bring abount a noticable difference once the files have been cached.
I would suggest testing the page render time in both cases and see how much improvement you see in your case and decide based on that information.
As a useful example, here are some stats from Xpedite (runtime minification tool I created a while back); note the difference in time from load to ready for combined vs uncombined scripts.
Combine all your JavaScript files into a single big file (thus minimizing the number of requests made to the server), and set its name to something like "application_234234.js"; the number represents the last time you have changed the file and will help the browser know it's a new file (thus no cache when you change it).
Add an Expires or a Cache-Control Header (set it really far into the future). Since the file name will change each time you'll modify it, you don't have to worry.
Last and not least, compress and gzip the JavaScript file.
These are some important advices, but learn more about best practices on: http://developer.yahoo.com/performance/rules.html
Common advice is to keep your CSS and JS files external. The reason: What you lose in the additional HTTP request*, you often gain back by not having to download cacheable static content (which CSS and JS usually is).
However, the smaller your external file, the more penalizing the additional HTTP request -- even if it is a 304 Not Modified response. So the smaller the external file, the more reason to favor inlining your CSS and JS content, at least when speed is your primary concern.
I ran some tests. Without going through the details, my results look like this:
External File Size Average Gain
----------------------------------
1KB -3.7ms
2KB -3.7ms
4KB -4.0ms
8KB -3.0ms
16KB -2.7ms
32KB 1.0ms
64KB 2.7ms
128KB 10.0ms
256KB 493.7ms
512KB 1047.0ms
1024KB 2569.7ms
My general conclusion is that using external files doesn't really matter until they get BIG. And by BIG, I mean the 50-100KB range... And that's minified and gzipped, if you take advantage of those.
Can anyone confirm or refute these results with additional data?
(* Assuming you don't use the HTTP "Expires" header)
I don't have additional data, but I can confirm that your results logically make sense. Most people today are on fast broadband connections, and most web servers will automatically gzip any text-based content that they send, so in many cases the overhead of sending a second request to load an external resource (or verify that it has not been modified) is going to be greater than the cost incurred by downloading a bit more data as part of the original request.
You can even work this out mathematically if you want, by assuming an average connection speed of 5 Mbps and a typical round-trip time of 100 ms. With those assumptions you will see that you can add up to approximately 62,500 bytes to the payload of the first request before the overhead of making the second request becomes justified. And that correlates very nicely with your numbers.
However, that doesn't mean that "using external files doesn't really matter", as there are other reasons to use them apart from the caching/page-load aspect. For instance, they help keep your code and overall site structure sane, particularly if you have common CSS styles and JavaScript utilities that are reused across multiple pages. I'd argue that this is at least as important as any small gain or loss in page-load time that you might get from using/not using external files. So in that context using external files makes sense even for smaller resources.
I am interested to know about the possibilities of reducing http requests on servers by sending different kind of contents in a single compressed files and later uncompress on client's browser and place the stuff(images,css,js) where it should be.
I read somewhere that firefox is working on plan to give such features in future releases but it has not been done yet plus it would not be a standard version.
Will you guys suggest any solution for this?can Flash be used to uncompress compressed files on client side for later use?
Thanks
We did more or less what you describe in our web an are extremely happy of the response time.
The original files are all separated (HTML, CSS, JS, images) and we develop on them.
Then when moving to production we have a shell script that:
use YUI compressor to compress CSS and JS
all images are read and converted to data:image/png;base64,...
all blank spaces and comments are removed from the HTML
all these resources are put inline in the HTML
The page is ~300kb and usually cached.The server gzip it, the real size travelling the network is then lower.We don't use any additional compression.
And then there is a second call to get the data(JSON for us) and start rendering it client side.
I had to read your question a few times before I got what you were asking. It sounds like you want to basically combine all the elements of your site into a single downloadable file.
I'm fairly confident in saying I don't believe this is possible or desirable.
Firstly, you state that you've heard that Firefox may be supporting this. I haven't heard about that, but even if they do, how will you be able to use the feature while still supporting other browsers?
But even if you can do it, you've tagged this as 'performance-tuning', on the grounds that you'll be saving a few http requests. But in your effort to save http requests to speed things up, you need to be cautious that you don't actually end up slowing things down.
Combining all the files may cut you down to one http request, but your site may then load slower as the whole thing would need to load before any of it would be ready for display (as opposed to a normal page load where your page load may take time but at least some of it may be ready for display quite quickly).
What you can do right now, and which will be useful for reducing http requests, is combine your stylesheets into a single CSS, your scripts into a single JS file, and groups of related images into single image files (google CSS Sprites for more info on this technique).
Even then, you need to be careful about which files you combine - the point of the exersise is to reduce http requests so you need to take advantage caching, or you'll end up making things worse rather than better. Browsers can only cache files that are the same over multiple pages, so you should only combine the files that won't change between page loads. So for example, only combine the Javascript files which are in use across all the pages on your site.
My final comment would be to re-iterate what I've already said: Be cautious about over-optimising to the point that you actually end up slowing things down.
Is it bad practice to have a single javascript file that gets loaded accross all pages even if certain functions are only needed on certain pages? Or should the files be split up according to functionality on a given page and loaded only by pages that need them?
According to YSlow less files is better, but try to keep each file under 25k. Also make sure you minify or otherwise reduce the size of the js (and css) files. If possible turn on GZip for js on the webserver and set a far future expires header.
See here for the Yahoo Developer performance best practices.
If this file is really large, it could impact certain user's perceived performance (i.e. download and render times). IMHO you should split it up into reasonable groups of functions, with each group having similar functions (such that pages only reference the files they need).
depends on the size and complexity of the unused functions.
the javascript-parser anyway only stores the location and the signature of each function. as far as i know, it is only parsed when executed.
if traffic is a problem for you, rather include only those you need...
regards
Since the JS files are cached once they are downloaded and the JS parser shows no noticable performance difference btw a big JS file(not a HUGE one ;)) and a small js file, you should go with the single file approach.
Also it is known that multiple js files reduces the performance.
You're best off with a single JS file, as browsers will cache it after the first request for it (unless they've turned that off, in which case they deserve what they get). Another thing that will vastly, vastly increase your perceived performance on page load is turning on gzip compression in the web server - most JS files compress very well.
I would recommend to use one big file, for each file the browser launches a web request. Most browsers, I'm not quite sure how much it is with the newest versions of the known browsers, only launch a few concurrent web requests. The browser will wait until the files have been downloaded before launching the next web requests.
The one big file will be cached and other pages will load faster.
As #Frozenskys mentions YSlow states that less files is better, one of the major performance enhancements proposed by the Yahoo team is to minimize the amount of http requests.
Of course if you have a HUGE javascript file that literally takes seconds to download, it's better to split it up to prevent that the user has to wait seconds before the page loads.
A single file means a single download; as this article explains, most browsers will only allow a limited number of parallel requests to a single domain. Although your single file will be bigger than multiple small ones, as the other answers have pointed out:
The file will be cached
Techniques like minification and server-side gzip compression will help to reduce the download time.
You can also include the script at the end of the page to improve the perceived load time.