November 18, 2009

Sixth Sense : Pranav Mishtry

Beyond words, do have a look at the following:

http://on.ted.com/7X

More on pranav mishtry goes at his website: http://www.pranavmistry.com/

I loved his quotation - "I know few things, now i need to learn what to do with these"

November 16, 2009

Comment of the day

Starting a new series guys!!! :-)

This one came from Debashish (my team mate at work) when India lost 4 significant early wickets but Rahul Dravid was still playing his one of the best innings:

"All the pillars are gone, but the wall doesn't need pillars to stand on the field"

November 07, 2009

On demand CSS and JS minimization (Java/PHP)

In web development CSS and JS play a very important role but at the same time, if you don't give proper attention, you may make your pages load really slow. I'm a yahoo fan for the standards and open technologies they have come up for the web. If you are a web developer, i strongly recommend these Exception Performance Blog and High performance websites.

Recently in my current work i'd to deal with a requirement where we had a couple of common JS libraries and some common CSS files along with some custom JS and CSS per user too. If you read the above two links, you must be thinking about JS and CSS compression for each of these files. There is an issue though, you will be hitting your server multiple times for each of these files. Since its common for a sufficiently large project to have multiple JS and CSS files, you've to make a choice between combining all the code into very few files vs keeping individual application logic separate. Well i decided to keep them separate :) This may sound absurd, but here is the learning from Y! days that helped me, i decided to not only load them in one go, but as well compress them. Thanks to YUICompressor (it was easy to adapt since its java based). As far as compression performance is concerned, once you compress it, you can always keep it cached for future transmissions. Some data on the performance:

JS - fairly complex (extjs based OO JS) - 1.4 MB - 532 msec - compression achieved 56%
CSS - fairly complex - 1.1 MB - 328 msec - compression achieved 52%

Now depending on the complexity of these source files, the compression might differ, but i'm confident it should not vary way too much from what i've mentioned above.

In our case, we had strict performance requirements to serve most of the requests in sub msecs, so we decided to go the caching way, otherwise i don't think on the fly compression of JS/CSS using YUICompressor is any bad (looking at the numbers above). Below is the code for the portion that does compression (again, its not mine, credit goes to the creators of YUICompressor, i just stripped this piece for my purpose)

JavaScriptCompressor compressor = new JavaScriptCompressor(
    new FileReader("original.js"), new ErrorHandler());
  StringWriter out = new StringWriter("new.js");
  int linebreakpos = 80;
  boolean munge = true, verbose = false, preserveAllSemiColons = false, disableOptimizations = false;
  compressor.compress(out, linebreakpos, munge, verbose,
    preserveAllSemiColons, disableOptimizations);
class ErrorHandler implements ErrorReporter {

  public void warning(String message, String sourceName, int line,
    String lineSource, int lineOffset) {
   if (line < 0) {
    System.err.println("\n[WARNING] " + message);
   } else {
    System.err.println("\n[WARNING] " + line + ':' + lineOffset
      + ':' + message);
   }
  }

  public void error(String message, String sourceName, int line,
    String lineSource, int lineOffset) {
   if (line < 0) {
    System.err.println("\n[ERROR] " + message);
   } else {
    System.err.println("\n[ERROR] " + line + ':' + lineOffset + ':'
      + message);
   }
  }

  public EvaluatorException runtimeError(String message,
    String sourceName, int line, String lineSource, int lineOffset) {
   error(message, sourceName, line, lineSource, lineOffset);
   return new EvaluatorException(message);
  }
 }
CssCompressor compressor = new CssCompressor(new FileReader("original.css"));
  StringWriter out = new StringWriter("new.css");
  int linebreakpos = 80;
  compressor.compress(out, linebreakpos);
One could very well pass a "null" instead of the ErrorHandler instance but make sure that verbose is set to false, else you will get a NPE. So this is just the compression part, what about reducing the number of requests?? Well so i created a servlet that basically takes all the required parameters for loading these static resources and serves them from cache or classpath (well some intelligence required here to avoid serving unwanted stuff but thats pretty straight forward. If you want to know what i did for this, post in comments and i will see if i should post that as well). And just FYI, Y! does similar thing for distributing such files through CDN. Just go to any of the pages on yahoo.com and you would see script urls of the kind
  • http://yui.yahooapis.com/combo?2.8.0r4/build/animation/animation-min.js&2.8.0r4/build/connection/connection-min.js&2.8.0r4/build/container/container-min.js
Now i'm not sure what is done in the backend, but i got this idea looking at their urls. And if you are wondering what if you want to use PHP, there is a similar project called Minify on google code which uses similar concepts borrowed from Y!'s guidelines. That's it for now... more to come!! :-)