Sunday, November 30, 2008

JavaScript packaging

With the current generation of browsers page load time is highly depended on the number of JS files loaded. Thus it makes sense to minimize the number of http-requests by combining multiple JS files in combined packages. This makes even more sense because the effectiveness of gzip-compression increases on larger JS files as opposed to the same source distributed over multiple files.

Most advanced JS projects will have some kind of mechanism within there build process to statically determine which JS files are needed for a particular page or application and assemble these together (JavaScript minification with a tool like the yui-compressor would also we applied at this point).

Here are some common simple strategies to make those JS packages:
  1. Traverse the JS directory recursively and put all files into the package
  2. Mantain a list of JS files per page/site/app and use that to assemple the JS packages
  3. Include support in the templating system to arrange for the generation of an appropriate JS package
We are currently using a modified version of strategy 2 at work. Every page loads a "meta" JS file that mostly defines an array of needed JS files. During development this file actually generates script tags via document.write to load the required files. This makes sense because during debugging you want to have errors and break points per file. Once we deploy the application for testing, a program analyzes those "meta" JS files to compile packages that are then loaded instead of the meta files.

In a recent post to the Joose mailing list, we talked about different strategies to find the ideal packages to minimize load time. My current thinking is that it is very hard to do much better than to load everything (for the whole app / sub-site) at once.

Here are some examples for strategies to determine what to put inside a JS package:

Page A needs JS file 1,2,3,4,5
Page B needs JS file 2,3,4,5,6

In order to minimize http requests, the strategies would be to

Strategy X:
1. Visit page A , load a package containing all needed JS files
2. Visit page B, once again load a package containing all needed JS files
  • plus: Simple
  • minus: Loading too much data
Strategy Y
1. Visit page A, load a package containing all needed JS files
2. Visit page B, somehow determine that we were already in Page A and use that package plus and extra request for file 6
  • plus: Minimal data
  • minus: Very complex, needs support on the server for dynamically assembling JS packages.
Strategy Z:
1. Visit page A Load a package containing all needed JS files for the entire App
  • plus: Simple
  • plus: Maximum result from zip-compression
  • minus: User loads code which he might not need eventually
My current thinking is, that if (and only if) the package resulting from strategy Z is not "too large" it is the best strategy most of the time.

If it is possible to easily determine disjunct packages of JS files, it makes of course sense to load these separately. In this case, it is, however, highly likely that we are talking about separate applications anyway.

Tuesday, November 25, 2008

JooseX: Joose extensions

First of all I want to say thanks for the kind words about Joose from the guys that attended my session at the hamburg barcamp.
I'm currently doing a lot of Joose programming at workt. It is kind of unfortunate that it won't be anything to show off from a JS perspective because the code is embedded into some serious worst-case legacy code. Anyway, Joose proves to be a very stable environment to build on and my personal focus will now shift toward extending Joose on the edges without bloating the core.
Those new extensions will live in the JooseX namespace and will be loosely coupled to the core so that they can be used on a case by case basis. Currently under development are the following modules:
  • Multiple roles for easy dumping of objects during debugging
  • A logging framework
  • A role for implementing the Singleton pattern.
  • A databinding framework that binds Joose objects to DOM elements (this is already in SVN called JooseX.DOMBinding.JQuery)
  • An MVC framework for event-driven client-sided programming (Although this is the most interesting part, it might not be released in its current form, because I'm still very much experimenting on this end)

Sunday, November 23, 2008

Joose presentation at barcamp hamburg #bchh08

I went to the Hamburg barcamp today. Overall the conference was great and most speakers really knew what they were talking about. My favorite session was done by a real bottom-dwelling SEO guy. Quite funny. Many thanks to Otto for providing the venue and free food and drinks.

I did a session about software development with JavaScript and Joose (based on the same presentation that I prepared for work 4 weeks ago. It was very well received and maybe Joose scored a couple more users.

Here are the slides that I showed today (I only changed the date):

Sunday, November 16, 2008

Joose 1.1 released

We are proud to announce the release of the newest version of Joose, the meta-object system for JavaScript.

You can download it on the Joose download page.

Version 1.1's main focus went into improving compatibility of Joose with other JS libraries and with user code that was not designed to run with Joose. During this release we also moved Joose's unit test suite to Jeremy's awesome new TAP based testing library.
Joose is now regularly tested to run together with these JS libraries:
  • jQuery
  • YUI
  • Prototype.js
  • MooTools
  • Dojo
Other changes are:
  • Joose is now compatible with the Rhino JavaScript engine. See this post for instructions.
  • Extending Object.prototype no longer breaks Joose (You should still not do it :)
  • Method modifiers in Roles are correctly applied to classes.
  • Roles can now define meta roles that are applied to the meta class of a class that is using the role.
  • The minified version of Joose is now compressed using the YUI compressor which saves 16 KB on the file. (Joose's file size is now 40 KB, 12 KB when GZipped)
  • Various bug fixes
We are still very actively working on the Joose type system that will be released with the next major release of Joose.

About Joose:

Joose is a self-hosting meta object system for JavaScript with support for classes, inheritance, mixins, traits, method modifiers and more.

Joose makes object-oriented programming with JavaScript easy, declarative and very productive. The Joose meta-object system is multi-paradigm. It supports class-based and prototype-based programming styles as well as class-based inheritance and role-based extention.

The Joose framework has been successfully used in multiple production systems for seven months now and has been proven to be very stable. Joose is being tested using an automated unit-test suite that is being run in all major browsers (Firefox, IE, Safari, Opera and Chrome).

Saturday, November 15, 2008

Joose now passes all tests under Rhino

Joose has been running alright under Rhino, but there have always been some failing tests due to different behavior in Rhino when compared to most other JavaScript engines.

Most JS engines traverse objects in declaration order. That means when you loop over an JS object like
isa: "SuperClass",
does: "Role",
methods: {
test: function () {}

the loop will return the properties in the object in the order "isa", "does", "methods".

Now because object literals are used to initialize Joose classes this traversion order can be really important when Joose is initializing classes. While all JS engines used in web browsers use the de-facto-standard traversion order, Rhino traverses objects in random order. It is important to state that the ECMAscript standard does specifically not define the traversion order, so from a standards point of view Rhino is right on this one.

While we might add automatic detection of Rhino to Joose, for now you will have to define this.CHAOTIC_TRAVERSION_ORDER = true in global scope before loading Joose to enable the work-around.

This work-around works like this. No matter how you write your class declarations, Joose will always evaluate the class properties "isa", "does", "has", "method", "methods" first (and in that order).

To try out Joose under Rhino check out Joose from svn and run playground/rhino/rhino_test.js with Rhino.

Monday, November 10, 2008

Offtopic: Looking for Nuclear engineers with JavaScript background

Please excuse this Spam in my own blog. My employer sinnerschrader is doing really well, we have lots of money to make it through the crisis and we are looking for:
  • Nuclear engineers with JavaScript background
  • Mossad Agents with Java affinity
  • Bored SAP slaves
  • and all other excellent Software-Engineers!
More info here or in this spot:

Monday, November 3, 2008

Joose test trial

We are preparing a new Joose release and we'd like to get feedback on test results under different configurations. If you have tests failures (or you don't) please post them here or at the mailing list:

As described in a earlier post, we can now run the Joose test suite under different real world scenarios. Because JavaScript is not very strong when it comes to separating code that is run within the same process there can always be side effects when code does weird stuff. We try to make Joose as robust as possible against these side effects.

The current known issues are
  • Google Chrome: Test file #7 crashes after 39 tests
  • All browsers: When run with Prototype.js two test in the jsonpickle test file fail
Here are the links to the different versions of the test suite:
Please report all failures. I personally tested with FF 3.0.3 on Mac, IE7, Safari 3 and Chrome.

Sunday, November 2, 2008

Turning all JSON web services into JSONP web services

I created a very simple Google App Engine application on Friday that helps you when somebody built a JSON based web service but did not mind to make it JSONP compatible (JSONP is a standard to do cross domain AJAX requests and it is supported by all major JavaScript libraries).

To use it simply call:
to us a customized callback parameters.

Here are some working examples:
Currently only GET requests are supported, so fully restful services are off limits. However, I guess, one could put in some more code to support different request methods.

To ensure that the payload is really JSON it is parsed and reencoded on the server.

I'm not really sure whether this service is secure enough. If somebody makes a point that it should be taken down then I will.