Website load performance - javascript

I was planning to improve my website load performance with public CDN using requirejs, so that I can have local fallback when public cdn fail. But soon, I found out that requirejs has the optimize function, which combines all required module into one big js file.
So, which one is the better practice and have better performance? Loads multiple JS files across multiple public CDN or one big JS file from local?

You forgot option 3: one big file from CDN. It's usually best to have as little requests as possible, because less than the network speed (kb/s), network latency is a problem.
But, if your code changes a lot (and users often return), it might be a reasonable idea, to concatenate all your libraries and plugins into one file and your own code into another, instead of having 1 big file all together.
This way, if you make a small change, it's not 1 big file that changes and has to be downloaded again, but a user will only need to get your script file and not the (unchanged) libraries again. And those outweigh the custom code by 10:1 in my experience.
Also, if you use a CDN link for jQuery, best case it's already in the users cache.
In the end I'd also advise you to test the different options (Chrome DevTools' network tab). I had a case where a CDN link was a perceivable slower than a "local" link (maybe due to my location, Australia).

It will depend on the nature of your website.
For instance, if most of the modules are required on most pages you'll benefit more for the bundled option.
If you have many modules and most modules only appear on a single/few pages, then you'll benefit more for the CDN option.
If you expect most traffic to come from repeat users, as opposed to unique users you might also benefit more from the bundled option.

Related

Single JS script or multiple scripts? [duplicate]

I'm used to working with Java in which (as we know) each object is defined in its own file (generally speaking). I like this. I think it makes code easier to work with and manage.
I'm beginning to work with javascript and I'm finding myself wanting to use separate files for different scripts I'm using on a single page. I'm currently limiting myself to only a couple .js files because I'm afraid that if I use more than this I will be inconvenienced in the future by something I'm currently failing to foresee. Perhaps circular references?
In short, is it bad practice to break my scripts up into multiple files?
There are lots of correct answers, here, depending on the size of your application and whom you're delivering it to (by whom, I mean intended devices, et cetera), and how much work you can do server-side to ensure that you're targeting the correct devices (this is still a long way from 100% viable for most non-enterprise mortals).
When building your application, "classes" can reside in their own files, happily.
When splitting an application across files, or when dealing with classes with constructors that assume too much (like instantiating other classes), circular-references or dead-end references ARE a large concern.
There are multiple patterns to deal with this, but the best one, of course is to make your app with DI/IoC in mind, so that circular-references don't happen.
You can also look into require.js or other dependency-loaders. How intricate you need to get is a function of how large your application is, and how private you would like everything to be.
When serving your application, the baseline for serving JS is to concatenate all of the scripts you need (in the correct order, if you're going to instantiate stuff which assumes other stuff exists), and serve them as one file at the bottom of the page.
But that's baseline.
Other methods might include "lazy/deferred" loading.
Load all of the stuff that you need to get the page working up-front.
Meanwhile, if you have applets or widgets which don't need 100% of their functionality on page-load, and in fact, they require user-interaction, or require a time-delay before doing anything, then make loading the scripts for those widgets a deferred event. Load a script for a tabbed widget at the point where the user hits mousedown on the tab. Now you've only loaded the scripts that you need, and only when needed, and nobody will really notice the tiny lag in downloading.
Compare this to people trying to stuff 40,000 line applications in one file.
Only one HTTP request, and only one download, but the parsing/compiling time now becomes a noticeable fraction of a second.
Of course, lazy-loading is not an excuse for leaving every class in its own file.
At that point, you should be packing them together into modules, and serving the file which will run that whole widget/applet/whatever (unless there are other logical places, where functionality isn't needed until later, and it's hidden behind further interactions).
You could also put the loading of these modules on a timer.
Load the baseline application stuff up-front (again at the bottom of the page, in one file), and then set a timeout for a half-second or so, and load other JS files.
You're now not getting in the way of the page's operation, or of the user's ability to move around. This, of course is the most important part.
Update from 2020: this answer is very old by internet standards and is far from the full picture today, but still sees occasional votes so I feel the need to provide some hints on what has changed since it was posted. Good support for async script loading, HTTP/2's server push capabilities, and general browser optimisations to the loading process over the years, have all had an impact on how breaking up Javascript into multiple files affects loading performance.
For those just starting out with Javascript, my advice remains the same (use a bundler / minifier and trust it to do the right thing by default), but for anybody finding this question who has more experience, I'd invite them to investigate the new capabilities brought with async loading and server push.
Original answer from 2013-ish:
Because of download times, you should always try to make your scripts a single, big, file. HOWEVER, if you use a minifier (which you should), they can combine multiple source files into one for you. So you can keep working on multiple files then minify them into a single file for distribution.
The main exception to this is public libraries such as jQuery, which you should always load from public CDNs (more likely the user has already loaded them, so doesn't need to load them again). If you do use a public CDN, always have a fallback for loading from your own server if that fails.
As noted in the comments, the true story is a little more complex;
Scripts can be loaded synchronously (<script src="blah"></script>) or asynchronously (s=document.createElement('script');s.async=true;...). Synchronous scripts block loading other resources until they have loaded. So for example:
<script src="a.js"></script>
<script src="b.js"></script>
will request a.js, wait for it to load, then load b.js. In this case, it's clearly better to combine a.js with b.js and have them load in one fell swoop.
Similarly, if a.js has code to load b.js, you will have the same situation no matter whether they're asynchronous or not.
But if you load them both at once and asynchronously, and depending on the state of the client's connection to the server, and a whole bunch of considerations which can only be truly determined by profiling, it can be faster.
(function(d){
var s=d.getElementsByTagName('script')[0],f=d.createElement('script');
f.type='text/javascript';
f.async=true;
f.src='a.js';
s.parentNode.insertBefore(f,s);
f=d.createElement('script');
f.type='text/javascript';
f.async=true;
f.src='b.js';
s.parentNode.insertBefore(f,s);
})(document)
It's much more complicated, but will load both a.js and b.js without blocking each other or anything else. Eventually the async attribute will be supported properly, and you'll be able to do this as easily as loading synchronously. Eventually.
There are two concerns here: a) ease of development b) client-side performance while downloading JS assets
As far as development is concerned, modularity is never a bad thing; there are also Javascript autoloading frameworks (like requireJS and AMD) you can use to help you manage your modules and their dependencies.
However, to address the second point, it is better to combine all your Javascript into a single file and minify it so that the client doesn't spend too much time downloading all your resources. There are tools (requireJS) that let you do this as well (i.e., combine all your dependencies into a single file).
It's depending on the protocol you are using now. If you are using http2, I suggest you to split the js file. If you use http, I advise you to use minified js file.
Here is the sample of website using http and http2
Thanks, hope it helps.
It does not really matter. If you use the same JavaScript in multiple files, it can surely be good to have a file with the JavaScript to fetch from. So you just need to update the script from one place.

Should I split my javascript into multiple files?

I'm used to working with Java in which (as we know) each object is defined in its own file (generally speaking). I like this. I think it makes code easier to work with and manage.
I'm beginning to work with javascript and I'm finding myself wanting to use separate files for different scripts I'm using on a single page. I'm currently limiting myself to only a couple .js files because I'm afraid that if I use more than this I will be inconvenienced in the future by something I'm currently failing to foresee. Perhaps circular references?
In short, is it bad practice to break my scripts up into multiple files?
There are lots of correct answers, here, depending on the size of your application and whom you're delivering it to (by whom, I mean intended devices, et cetera), and how much work you can do server-side to ensure that you're targeting the correct devices (this is still a long way from 100% viable for most non-enterprise mortals).
When building your application, "classes" can reside in their own files, happily.
When splitting an application across files, or when dealing with classes with constructors that assume too much (like instantiating other classes), circular-references or dead-end references ARE a large concern.
There are multiple patterns to deal with this, but the best one, of course is to make your app with DI/IoC in mind, so that circular-references don't happen.
You can also look into require.js or other dependency-loaders. How intricate you need to get is a function of how large your application is, and how private you would like everything to be.
When serving your application, the baseline for serving JS is to concatenate all of the scripts you need (in the correct order, if you're going to instantiate stuff which assumes other stuff exists), and serve them as one file at the bottom of the page.
But that's baseline.
Other methods might include "lazy/deferred" loading.
Load all of the stuff that you need to get the page working up-front.
Meanwhile, if you have applets or widgets which don't need 100% of their functionality on page-load, and in fact, they require user-interaction, or require a time-delay before doing anything, then make loading the scripts for those widgets a deferred event. Load a script for a tabbed widget at the point where the user hits mousedown on the tab. Now you've only loaded the scripts that you need, and only when needed, and nobody will really notice the tiny lag in downloading.
Compare this to people trying to stuff 40,000 line applications in one file.
Only one HTTP request, and only one download, but the parsing/compiling time now becomes a noticeable fraction of a second.
Of course, lazy-loading is not an excuse for leaving every class in its own file.
At that point, you should be packing them together into modules, and serving the file which will run that whole widget/applet/whatever (unless there are other logical places, where functionality isn't needed until later, and it's hidden behind further interactions).
You could also put the loading of these modules on a timer.
Load the baseline application stuff up-front (again at the bottom of the page, in one file), and then set a timeout for a half-second or so, and load other JS files.
You're now not getting in the way of the page's operation, or of the user's ability to move around. This, of course is the most important part.
Update from 2020: this answer is very old by internet standards and is far from the full picture today, but still sees occasional votes so I feel the need to provide some hints on what has changed since it was posted. Good support for async script loading, HTTP/2's server push capabilities, and general browser optimisations to the loading process over the years, have all had an impact on how breaking up Javascript into multiple files affects loading performance.
For those just starting out with Javascript, my advice remains the same (use a bundler / minifier and trust it to do the right thing by default), but for anybody finding this question who has more experience, I'd invite them to investigate the new capabilities brought with async loading and server push.
Original answer from 2013-ish:
Because of download times, you should always try to make your scripts a single, big, file. HOWEVER, if you use a minifier (which you should), they can combine multiple source files into one for you. So you can keep working on multiple files then minify them into a single file for distribution.
The main exception to this is public libraries such as jQuery, which you should always load from public CDNs (more likely the user has already loaded them, so doesn't need to load them again). If you do use a public CDN, always have a fallback for loading from your own server if that fails.
As noted in the comments, the true story is a little more complex;
Scripts can be loaded synchronously (<script src="blah"></script>) or asynchronously (s=document.createElement('script');s.async=true;...). Synchronous scripts block loading other resources until they have loaded. So for example:
<script src="a.js"></script>
<script src="b.js"></script>
will request a.js, wait for it to load, then load b.js. In this case, it's clearly better to combine a.js with b.js and have them load in one fell swoop.
Similarly, if a.js has code to load b.js, you will have the same situation no matter whether they're asynchronous or not.
But if you load them both at once and asynchronously, and depending on the state of the client's connection to the server, and a whole bunch of considerations which can only be truly determined by profiling, it can be faster.
(function(d){
var s=d.getElementsByTagName('script')[0],f=d.createElement('script');
f.type='text/javascript';
f.async=true;
f.src='a.js';
s.parentNode.insertBefore(f,s);
f=d.createElement('script');
f.type='text/javascript';
f.async=true;
f.src='b.js';
s.parentNode.insertBefore(f,s);
})(document)
It's much more complicated, but will load both a.js and b.js without blocking each other or anything else. Eventually the async attribute will be supported properly, and you'll be able to do this as easily as loading synchronously. Eventually.
There are two concerns here: a) ease of development b) client-side performance while downloading JS assets
As far as development is concerned, modularity is never a bad thing; there are also Javascript autoloading frameworks (like requireJS and AMD) you can use to help you manage your modules and their dependencies.
However, to address the second point, it is better to combine all your Javascript into a single file and minify it so that the client doesn't spend too much time downloading all your resources. There are tools (requireJS) that let you do this as well (i.e., combine all your dependencies into a single file).
It's depending on the protocol you are using now. If you are using http2, I suggest you to split the js file. If you use http, I advise you to use minified js file.
Here is the sample of website using http and http2
Thanks, hope it helps.
It does not really matter. If you use the same JavaScript in multiple files, it can surely be good to have a file with the JavaScript to fetch from. So you just need to update the script from one place.

When to use Requirejs and when to use bundled javascript?

This may be a dumb question for web guys. But I am a little confused over this. Now, I have an application where I am using a couple of Javascript files to perform different tasks. Now, I am using Javascript bundler to combine and minify all the files. So, at runtime there will be only one app.min.js file. Now, Requirejs is used to load modules or files at runtime. So, the question is if I already have all things in one file, then do I need requirejs? Or what is a use case scenario where I can use requirejs and/or bundler?
Please let me know if any further details are needed.
Generally you only use RequireJS in its loading form during development. Once the site is done and ready for deployment, you minify the code. The advantage here is RequireJS knows exactly what your dependencies are, and thus can easily minify the code in the correct order. Here is what it says on the RequireJS website:
Once you are finished doing development and want to deploy your code for your end users, you can use the optimizer to combine the JavaScript files together and minify it. In the example above, it can combine main.js and helper/util.js into one file and minify the result.
This is a hotly contested issue among many proficient javascript developers. Many other languages have a "compilation" phase where the entire program is bundled up for deployment (JBoss's .WAR files come to mind). Programmers that come from more traditional backgrounds often favor this approach.
Javascript has seen such growth in recent years that it is difficult to chart exact best practices, but those that appreciate the more functional nature of Javascript often prefer the module loading approach (like require.js uses).
I wrote Frame.js which works much like require.js, so my bias is towards the module loader approach.
To answer your question directly, yes, it is one or the other.
Most that argue for packing your scripts into a single file believe it enables more compression and is thus more efficient. I believe the efficiency advantages of packaging are negligible in most cases because: (1) module load times are distributed over the entire session, (2) individual modules can be compressed to nearly the same percentage, (3) individual modules can be cached by the server and routers separately, and (4) loading scripts only when they are needed ultimately allows you load less code for some users and more code overall.
In the long run, if you can see an advantage to dynamic script loading use it. If not, bundle your scripts into a single file.
It depends on your application. If you're making a server-side app with only modest javascript (less than 100kb minified) then go for total bundling, you're probably going to be fine.
But if you're making a javascript app and have a ton of code in it, then your needs are going to be different.
For example, in my app I bundle all the core files. There's jQuery, underscore, backbone, my main app files, my user login system, my layout system, my notifications and chat system, all are part of my big initial file.
But I have many other modules as well that isn't part of the initial bundle, that are loaded after those.
The forums, the wiki, the wysiwyg, color picker, drag/drop, calendar, and some animation files are part of the second category. You need to make reasonable decisions about what's commonly used and needed immediately vs what can be delayed.
If I include everything immediately I can get above a meg of javascript, which would be insane and make the initial boot unacceptably slow.
The second category starts downloading after initSuccess event fires from the initial file.
But the second category is more intelligent than the first in that it loads what's more important first. For example if you're looking at the wiki it'll load the wiki before it loads the color picker.

Bundling .js files vs CDN

In order to improve performance of our web pages, we are recommended to use CDNs to serve .js files on our web pages. That makes sense.
Also, we are recommended to bundle our .js files in order to reduce the number of requests which are being made to server on load.
So, we need to sit down and make decision between if we use CDN or bundle .js files.
What are the pros and cons? Which ones make more sense?
Why can't you bundle them and place them are the CDN? It should hardly be a decision of one or the other?
If you have to choose one or the other, it depends on how many .js files you are including. For a small number of files, I'd suggest that a CDN would be quicker, where-as for a greater number of files, a bundle of .js files would definitely be quicker. Where the switch-over would be, is something for you to experiment with.
My answer: both. Bundle them and place them on a CDN.
The downside of doing this? Depends. What does you build process look like? Can you easily automate the bundling and minification? Are you using Yahoo YUI or Google Closure or something else?
Also, if there is a lot of GUI dependent jQuery there might be some time consuming friction due to constantly changing elements/effects/css.
Testing is important too because due to possible minification quirks.
Bottom line: 5 javascript files safely bundled into 1 file === 4 fewer requests.
A page with just plain old Html and one external javascript reference === 2 requests to your server. However, a page with just plain old Html and one external javascript reference on a CDN === 1 request to your server.
Currently we are using the Google Closure tools. The Google Closure Inspector helps with the following:
Closure Compiler modifies your original JavaScript code and produces code that's smaller and more efficient than the original, but harder to read and debug. Closure Inspector helps by providing a source mapping feature, which identifies the line of original source code that corresponds to the compiled code.
As others have already stated, the answer is both if possible. Bundled (and minifying) gives a benefit to your users because it decreases the page weight. The CDN benefits your servers because you are offloading work. Generally speaking, you need not optimize either unless you have observed performance issues or you just have nothing better to do.
There's a few things you need to think about...
How much of the JS do you need to load early in the page load, and how much can you delay until later?
If you can delay loading JS (e.g. put it at the bottom of the page) or load it asynchronously as Google Analytics does, then you will minimise the amount of time downloading the JS spends blocking the UI thread.
After working out how the load of the JS can be split, I'd deal with the merge / minify of the various JS files - cutting down HTTP requests is key to improving performance.
Then look at moving to the CDN and ensure the CDN can serve the JS content compressed and allow you to set headers so it's "cached forever" (you'll need to version the files if you cache forever). A CDN helps reduce the latency but will also reduce size by being cookieless
Other thing you might want to consider is setting up a separate domain for static content, point it to your server(s) while you sort things out and then switch to a CDN if it looks worthwhile.
Andy

Multiple JavaScript files, combine into one

I am developing in ASP.NET MVC and using multiple JavaScript files. E.g. jQuery, jQuery UI, Google Maps, my own JavaScript files, etc.
For performance, should I combine these into one? If so, how?
The reason you want to combine many files into one is so to minimize latency of setting up and tearing down http requests, the fewer you make the better. However, many newer browsers are downloading JavaScript files in parallel (still executing sequentially). The consequence is that downloading a single 1Mb file may be slower than three 350Kb files. What I've come to do is to separate my files into three bundles:
External lib files (jquery, flot, plugins)
Internal lib files (shared by multiple pages)
Page specific files (used only by that page, maybe by two pages)
This way, I get the best of both worlds: not an excessive number of http requests at startup, but also, it's not a single file that can't benefit from parallel downloads
The same applies to CSS, each page load three CSS bundles. So in total, our pages download six bundled files plus the main html file. I find this to be a good compromise. You may find that a different grouping of files works better for you, but my advice is don't create a single bundle, unless it's a one page app. if you find yourself putting the same file into different bundles a lot, it's time to re-think the bundling strategy since you're downloading the same content multiple times.
What to use? Martijn's suggestions are on the money. YUI is the most widely used from my experience, that's what we used at my previous and current jobs.
For the question of whether you should, check out the link in Shoban’s comment.
For the question of how:
Google’s Closure Compiler
Yahoo!’s YUI Compressor
If they are all going to be included on all of your pages, then it doesn't really make a difference. But if some are only relevant to certain pages, it would technically be better to keep them separated and only include the relevant ones on relevant pages.
As far as I know, you should indeed : less files means less http get, hence better performance for the user when they first load the page.
So they will save a split second they will come on your page for the first page. But after, these files are cashed, and it makes then no difference at all...
I haven't digged into the javascript engines itselves, but a function in one file will be handled in the same way if it is in a big file or a small file. So it makes no difference in the execution.
So, save your time, don't change anything as it'll cost you too much time for too little reward, especially when you'll discover that you want the latest version of jquery (a new version came out today btw), and that you have to re-concatene everything...

Categories

Resources