Bundling .js files vs CDN - javascript

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

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.

Put javascript and css inline in a single minified html file to improve performance?

A typical website consists of one index.html file and a bunch of javascript and css files. To improve the performance of the website, one can:
Minify the javascript and css files, to reduce the file sizes.
Concatenate the javascript files into one file and similar for the css files, to reduce the number of requests to the server. For commonly used (and shared) libraries like jquery it makes sense to leave them external, allowing the browser to cache the library and reuse it in different web applications.
I'm wondering if it makes sense to put the concatenated javascript and css file inline in on single html file, which will reduce the number of requests even further. Will this improve the performance of your site? Or will it work reversed, making it impossible for the browser to cache anything?
Concatinating your CSS and JS files into one file will reduce the number of requests and make it load faster. But as commented, it won't make much sense unless you have a one-page site and the load time of that page is very critical. So you're better off to separate CSS from Javascript in my opinion.
Here's a book where you can learn more about the topic:
High Performance Web Sites
this tools maybe help you.
Turns your web page to a single HTML file with everything inlined - perfect for appcache manifests on mobile devices that you want to reduce those http requests.
https://github.com/remy/inliner
It would cut down on the number of requests but it would also mean no caching of those for use on other pages. Think of defining an external file as also a way to tell the browser "and this section of the site is reusable". You'd be taking that ability away and so the CSS and JS would load. Like jackwanders said it's great if you only have one page.
This is not a good idea for the following reasons:
You will not enjoy the benefit of cache
You will load unneeded resources in all of your pages
You will have a hard time while developing your website because of large files with unrelated code branches
If you work in a team you will have to work with your teammates on the same files always, which means that you will have a lot of merge conflicts.
You can have a single CSS for all your pages and since it will be cached, the subsequent pages will refer it from cache without sending extra request.
However, putting all Javascript files is into one is contextual.
Most probably you might be using libraries like jQuery, and relevant plugins. This 'might' throw conflicting issues between plugins. So, before you try it all at once, try merging few files at once and checking if the error pops or not.

Minification for Css/Js - right way?

In my project each page has a bunch of dependent Javascript and Css. Whilst developing I just dumped this code right into the page but now I'm looking to clean it up...
it appears that the general approach out there is to package all the Javascript/CSS for an application into two big files that get minimised.
This approach has the benefit that it reduces bandwidth since all the front-end code gets pulled in just once from the server... however, I'm concerned I will be increasing the memory footprint of the application by defining a whole ton of functions for each page that I don't actually need - which is why I had them on a per-page basis to begin with.
is that something anyone else cares about or is there some way to manage this issue?
yes, I have thought of doing conditional function creation since I need to run code conditionally for each page anyway - though that starts to get a bit hackish in my view.
also, is there much cost to defining a whole ton of Css that is never used?
Serving the javascript/CSS in one big hit for the application, allows the browser to cache all it needs for all your pages. If the standard use case for your site is that users will stay and navigate around for a while then this is a good option to use.
If, however, you wish your landing page to load quickly, since there is a chance that the user will navigate away, consider only serving the CSS/javascript required for this page.
In terms of a performance overhead of a large CSS file - there will be none that is noticeable. All modern browsers are highly optimised for applying styles.
As for your javascript - try not to use conditional function creation, conditional namespace creation is acceptable and required, but your functions should be declared only in one place.
The biggest thing you can do for bandwidth is make sure your server is compressing output. Any static document type should be compressed (html, js, css, etc.).
For instance the jQuery Core goes from approx. 90KB to 30KB only because of the compressed output the server is sending to browsers.
If you take into account the compression, then you have to create some mammoth custom JS includes to really need to split-up your JS files.
I really like minifying and obfuscating my code because I can put my documentation right into the un-minified version and then the minification process removes all the comments for the production environment.
One approach would be to have all the shared javascript minified and compressed into one file and served out on each page. Then the page-specific javascript can be compressed/minified to its own files (although I would consider putting any very common page's javascript into the main javascript file).
I've always been in the habit of compressing/minifying all of the CSS into one file, rather than separate files for each page. This is because some of the page-specific files can be very small, and ideally we share as much css across the site as possible.
Like Jasper mentioned the most important thing would be to make sure that your sever is GZIPing the static resources (such as javascript and css).
If you have a lot of javascript code you can take a look on asynchronous loading of js files.
Some large project like ExtJs or Qooxdoo have build in loaders to load only required code, but here is a lot of libs which simplify this, and you can use in your project (e.g. head.js, LAB.js).
Thanks to them you can build application which loads only necessary files, not whole javascript code which in case of big apps can be a heavy stuff for browser.

Categories

Resources