Saturday, January 22, 2011

GwtQuery CSS Selectors Performance


Lately I've been working on the gwtquery opensource project, a rewrite in Gwt of the popular jquery javascript library.
Like jquery, which helps javascript developers to handle DOM elements and events, gquery helps java developers to do the same, and both share the same API with almost the same methods and behaviour.

One of the most powerful features in jquery is the ability to select elements using css selectors. In this matter, gquery improves the performance using two gwt techniques:
  • Generating permutations and selecting the more suitable engine selector for each browser .
  • Being able to analyse the css selector at compile-time and optimize the generated code.
Based on these, Gquery generates the most appropriate strategy for each browser, not only considering performance but the final javascript size.

One of the tasks I've faced along this time working with gquery, is to improve the performance of selectors adding new engines, testing them, and choosing the faster one for each browser.

There is a benchmarking application in gwtquery to compare the performance between each engine implementation. It is inspired in the Slickspeed test, taking from it the list of selectors to compare and the DOM document.
I have run this benchmark in several combinations of browsers and operating systems, and finally I have put the results into a spreadsheet to easily compare it and generate some charts.

Premises

  • I have used the browsers most used nowadays, and the operating systems I have in my virtualbox machines.
  • I have selected a bunch of the most popular javascript frameworks (jquery_1.3.1, dojo_1.4.3, prototype_1.6.0.3) and javascript selectors (sizzle_1.0, domassistant_2.7).
  • Gquery can run in two modes, gwt_compiled meaning that the compiler is able to parse each selector used in the application and generate optimized js code, and gwt_dynamic which evaluates selectors in runtime time like the rest of libraries.
  • In browsers where native optimizations are not available, Gquery falls back to a pure JSNI implementation based on Sizzle.
  • During my testing, I realised that there are browsers performing worse than others, so I had to make three groups, and each group has a different time scale to easily see the results.
  • Newer IE8 releases comes with a native selector which is only available in standard mode.
  • The unit used in all tables and charts is the millisecond, meaning the accumulated time spent to run each single slickspeed css selector.

Comparison between frameworks

This table shows the results of my tests. As you can see, gwtquery in compiled mode always beats, and in general gwtquery dynamic performs better than any other library.

Comparison between browsers:

This table demonstrates that there are browsers performing better than others. In general, opera, chrome, safari and firefox-3.6 handle DOM selectors very well, firefox-3.0 and IE8 (in standars mode) performs acceptable, and other versions of IE performs quite bad.

Conclusions

  • GwtQuery in compiled mode is the faster javascript library to select dom elements.
  • GwtQuery dynamic selectors are, in most cases, faster or equal than any other library.
  • GwtQuery performs better than its brother jQuery.
  • Sizzle is faster than other libraries, this is the reason why gwtquery fall back js implementation is based on it.
  • The javascript produced by the Gwt compiler performs well, and normally better than the javascript written by hand.
  • There are considerable differences between the performance of different browsers. The most significant is the behaviour of IE, although last changes introduced in IE8 are promising.
  • Gecko browsers perform worst than browsers based on webkit, nevertheless the version used in FF-3.6 has many improvements.