views:

97

answers:

3

I'm currently developing an application that will be run on local network in B2B environment. So I can almost forget about micro(mini?) optimizations in terms of saving bandwidth because Hardware Is Cheap, Programmers Are Expensive.

We have a well structured Object oriented js code in the project and obviously lots of js classes. If all the classes will be stored in separated files then it will be quite easy to navigate through this code and hence maintain it.

But this will bring my browser to generate a couple dozens of HTTP requests to get all the js files/classes I need on the page. Even in local environment it is not super fast on first load(with empty cache), and later when you modify it and cache has to be invalidated.

Possible solutions:

  • violate rule "one class per file"
  • use YUI compressor all the time(in development & production) for generating one big js file.

But if we choose YUI compressor for this(no minify action in dev environment, and minify for production) - then we need to reload/recompile this big js file on every modification in any js file.

What would you recommend for solving this problem?

+3  A: 

Keep all the .js files separate. Keep your "one class per file" rule.

Then, use a server-side technology to aggregate the script into one request.

Options:

  1. Use an ASPX or PHP or whatevver server-side scripting thing you have, to aggregate all the JS into one request. The request for a .js is no longer a static file, but with caching on the server it should be relatively cheap to serve.

  2. Use Server Side Includes in a consolidated .js file.

    <!--#include virtual="/class1.js"-->
    <!--#include virtual="/class2.js"-->

Cheeso
could you give a more detailed example of how to use #include virtual=?
Gutzofter
Check it out: http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/eced0b89-e052-42ff-baa8-751dd191c3b5.mspx?mfr=true
Cheeso
thanks for the ssi info
Gutzofter
+3  A: 

Your approach of having separate files for each class is good - practices that make development easier are always good.

Here's some tips for making the loading faster:

  • Compress your code. As you say, you could use YUICompressor, or the newly released Google Closure Compiler.
  • When concatenating multiple files into one, think of what you need and when: If you only need files A, B and C when the app starts, but not Z and X, put only A, B and C into a single file. Load another file with Z and X concurrently after A/B/C.
  • You can use Firefox plugins YSlow and Page Speed to test for load performance bottlenecks

As you mention, you would need to rerun the compressor each time you make a change. I don't think this is a big problem - on a decent machine, it should run pretty fast even with a lot of files. Alternatively, you could use a daily build process using some tool, which could build the latest revision from your source control (you do use scm, right?), and run unit tests and deploy if everything goes OK.

I would recommend using Ant or some other automation tool to create a build script. This will make it as simple as running one command to build your compressed script, reducing the repetitive work you would otherwise need to do. You could even have Ant deploy your code to the server.

Jani Hartikainen
+1  A: 

You may have the best of both worlds - a development environment with one class per js file without the need to compile/deploy for every iteration AND one (or several) concatinated larger js files (minified if desired) in production.

Depending on your build environment this may be setup in a number of different way, but using ANT may be the easiest way. Using ANT you can run tasks for both concatination and minification (running YUICompressor through the Java task). This will produce the concatinated and minified large js file.

However, to maintain productivity you want to avoid doing this for every code iteration. Changing the tags from one to several (for every class file) is out of the question.

So, you load your big js file as expected:

<script src="application.js"></script>

When deploying to production this file is the concatinated/minified version of all your js files.

However, during development this file is a bootstrap/loader file that simply loads all your individual js-files (illustrative example using jQuery).

$.getScript('/class1.js');
$.getScript('/class2.js');
$.getScript('/class3.js');
$.getScript('/class4.js');
$.getScript('/classn.js');
....

If you are using YUI 3 look into the module behavior and how to specify dependencies.

Using different ANT targets the generation and copying of these files to the correct location may easily be managed.

And now you may simply reload your browser whenever you need to test a change in a file, but get the performance benefit during production. All without sacrificing productivity or maintainability.

stefpet
I was thinking about jQuery's getScript function for this task. This function has a possibility to run a callback function, when desired script is loaded and executed. Do I need to make nested callback calls to be sure, that all the classess are loaded in the right order? Like this: $.getScript("test1.js", function(){ $.getScript("test2.js", function(){ $.getScript("test3.js" )}) });
Fedyashev Nikita