Showing posts with label jsslickspeed. Show all posts
Showing posts with label jsslickspeed. Show all posts

Tuesday, September 28, 2010

jQuery,Ext custom css selectors: avoid the framework war

In the last entry, we saw how javascript frameworks compare when using css3 standard selector queries. Now, we will see how those frameworks compare when using custom css selectors,ie,not W3 standard selectors. jQuery is well known for implementing very nice shortcuts like ":input", ":radio" or ":even",":odd". We will see how these shortcuts are handled and see that you should avoid them when possible and stay away from the framework war...

Test using jsslickspeed


jsslickspeed is a fork of slickspeed containing both standard selectors and custom selectors tests + document.querySelectorAll when available.

Read the result for the standard selectors

Same frameworks, same browsers tested.
We will look into the custom css selectors test in this entry. You can run the test yourself.

CSS3 custom selectors result


It is not necessary to go through each browser results to say that frameworks custom implementation slows down from little to greatly the speed of the test.

You can find all the result charts at the end of this article but let's sum up...
  • Custom selectors not handled by libraries does not throw any error
Obviously, not all libraries implement the same selectors...
most of them implement the attribute negation look up "!=", the pseudo-class ":contains" and some of them ":even" and ":odd".
This basically means that we enter in a non-standard world where the selectors you were using with one framework may not work, even worse, send back results instead of throwing an error.
Well, if you are a jQuery guru, an ExtJS guru, using each framework custom selectors within one project is not going to be harmful but you may need to switch of javascript framework for your new job and you will have to learn anew what you can use and what you can not use. If you force yourself to use standard selectors, this problem will not occur.
  • Native standard selectors are most of the time faster than the custom ones 
some concrete examples:

jQuery ":parent" tooks 8ms against 1ms for ":not(:empty)"  in Firefox 3.6...

jQuery "div > *:input" took 115ms against 4ms for its counter part (i have to say that the native one is very long: div > input,div > select,div > textarea,div > button) in IE6

jQuery ":submit" tooks 20 ms against 1ms for "[type=submit]" in Firefox even though the doc seems to specify cross-browser issue being handled...

":odd" and ":even" takes about 13ms against 3ms for ":nth-child(even|odd)" for jQuery while Ext JS which implements these shortcuts too took a constant time. READ BELOW FOR A POSSIBLE REASON
  • Custom shortcuts are not implemented the same way...
It seems like we are in the "browser war" again where each framework wants to implement its extra feature to make the difference...because it sounds better this way...
This get tricky though.
jQuery implements :even and :odd has a shortcut for nth-child(even) and nth-child(odd) with the difference that it is a 0 based indexed whereas the W3 standard states a 1 indexed based calculation.
But well, it could be ok if...
  • Shortcuts may not work properly
jQuery returned exactly the same result for both :even and :odd...

Looking at the result you will see the library returns the exact same number for those two selectors...so : div > p:even == div > p:odd. Both of them different from div >p:nth-child(even) and div > p:nth-child(odd)...
Ext also implements the :even and :odd shortcuts but does follow the W3 standard declaration and use an index starting from 1. It does send back two different results for :even and :odd and these results do match there standard counterparts, nth-child(odd|even).
  • Custom selectors... are not interoperable
Yes, like the old time,with browsers implementing their own javascript APIs because it seemed great at the time. This left us with an horrifying war-land where no browser could be trusted...
ok, I am a little bit dramatic here but come to think of it...
If browsers decide to implement :even,:odd or :input but that they use for the first ones, the standard definition starting from 1? Libraries will have to resort to their own implementation in order to keep older applications running,eventually, slowing down the entire process. If :input is implemented but only send back input tag fields? The same here...

Being a good citizen and avoid the framework war


All these shortcuts/customs selectors, not available by default are very useful and tempting but...
Obviously when you use a shortcut or a custom selector, libraries will have to use their own engine instead of using the native selector when available.

What does it mean?
  •   It will be slower most of the time. You loose the speed of the native selector.
  •  You loose the checking done by the native selector who has a real low level lexer(most of the libraries will silently return something instead of throwing an error when you write an unsupported selector) 
  • Uncoherent implementation between frameworks is at best confusing at worst could lead to problem if the browser implements themselves these shortcuts. (let's say :even and :odd is implemented and are equal to nth-child(odd|even)... some libraries will have to resort to their own engine for compatibility issues and you will loose all the benefit of the native selector implementation).
As a result and for better interoperability you should use as much as possible the standard selectors.

If you can use a standard selector in lieu of a custom selector, please do so...It will be,well, standard, interoperable and faster for new browser and sometimes even older ones,for example:

:parent use :not(:empty)

:even use nth-child(even)

:odd use nth-child(odd)

:input use input,select,textarea,button
For this one,if it is too long,most of the time your mark up should allow you to target them anyway like #formContainer label *. Obviously it does link your javascript to the underlying html layout which is not ideal...



Below are the results for the custom selectors:

Safari 5 (Win) CSS3 custom selectors IE6 Emulated CSS3 custom selectors IE8 CSS3 custom selectors IE7 CSS3 custom selectors Chrome 6 (Win) CSS3 custom selectors

Monday, September 27, 2010

jsslickspeed: css3 selectors testing frameworks (jquery,dojo,mootools,prototype,yui,ext...) vs browser

How to create your own basic css selector in javascript.This was the plan for the next entry.Having a grasp of how this can be implemented could help many to improve the css selectors they use with their favorite framework. But before this article,it would be nice to know where actual javascript frameworks stands against one an other (including custom selectors created by some frameworks )and against the native implementation,document.querySelectorAll. Some results will be surprising...

Libraries tested


First things first, a list of the library tested:
  • Prototype 1.6.1.0
  • Mootools 1.2.4
  • Ext js 3.1.0
  • Dojo 1.5
  • jQuery 1.4.2
  • YUI 3.2.0
  • RightJS 2.0
  • document.querySelectorAll (when available in the browser).
I've included RightJS 2.0 in this tests as it was claiming to be the fastest (well, it's only a fraction of the framework that is tested) but unfortunately the css selectors supported are few...
We will see an in depth view of the results.

The test runner : jsslickspeed

jsslickspeed is a fork of slickspeed to use only javascript and add document.querySelectorAll in the list when available. Only tested with the following browsers so far:
  • IE6 (emulated with IETester)
  • IE7 (IE8 emulatation mode)
  • IE8
  • FF3.6
  • Safari 5
  • Chrome 6
jsslickspeed allows to load scripts from different servers too as I wanted to use google cdn when the library was available .

Tests contents

2 tests:
If the standard selectors test does not need further explanation, the custom selectors test may need some explanation.
The frameworks offer some shortcuts, ie, :even or :radio or :submit, :contains, [attr!=foo]. We will see that these custom selectors are not implemented in the same way, may slow down the process and could even be buggy.

CSS3 standard selectors

The test uses mostly the same selectors as the original slickspeed, I've just added some few selectors but nothing tricky (like weird construct to see how the library handles them).
  • Let's start with IE series: IE6,IE,7 and IE8.
IE8 does have a document.querySelectorAll but unfortunately does not support css3 selectors.
The only one to fall in this pitfall is... RightJS. Having document.querySelectorAll does not mean that the browser supports css3 selectors.
This basically means that you can not write safely the same selectors across browser... Hope this bug will be fixed.

 IE8

The IE implementation of the selector is rather fast but does not support 11 selectors (and therefore,Right JS only using the native implementation without adding extra parser functionality when required has the same errors. The speed is not representative for this library here).
Dojo is the fasted followed by jQuery. YUI is extremely slow followed by Prototype, Mootools and Ext JS.

Moving on to IE7...
This version of IE and below do not implement document.querySelectorAll.All the libraries use therefore their own css selector parser and implementation:

IE7 CSS3 standard selectors

We can see that RightJS goes out of the roof but does not implement properly 15 selectors (attribute selectors,ie [class=example],are all wrong). YUI and Prototype are as slow as in IE8 but we can see that Ext JS and Mootools are faster than jQuery while Dojo is still the fastest.

Let's move on to IE6...

IE6 Emulated CSS3 standard selectors

Well, no real surprises, this is slow...
Ext JS is the first of all and Dojo, jQuery,Mootools follow. YUI,Prototype and RightJS(buggy anyway) are outsiders.
It is to note that Prototype has some selectors that make its result jumps... "div ~ p" for example takes about 450ms where other frameworks are between 40~100ms. All the attribute selectors are around 200ms and p:nth-child(n) is at 300ms against a 20~40ms for the others.

As a conclusion on the IE series:

IE8 does offer a native selector but unfortunately, by not implementing the css3 selectors can not be used reliably unless you intend to use only css2 selectors in your projects.
You should avoid RightJS if you intend to develop with css3 selectors in mind.
As for the speed concern, it would be too easy to reduce a library to its sole implementation of css selectors and if the speed is an indicator it can not be used a the primary reason to elude a framework(unless you intend to use heavily complex selectors beyond class selectors, id selectors and descendant selectors).

  • Firefox

FF3.6.1 (Win) CSS3 standard selectors

This gets better!
Prototype gets back in the track while misteriously Mootools and Ext are the slowest. But even the slowest is at around 230ms when compared to the 1400ms in IE8, this is really nothing!

Obviously the native selector of Firefox is the fastest of all and now YUI is the first in the list.
Most of the libraries use the native implementation behind the scene and add some extras that's why the result gets tighter.

Notice that Firefox implementations requires about 40ms to do the tests.

  • need for speed or Chrome:
Chrome 6 (Win) CSS3 standard selectors

Makes no surprise here but Chrome is blazing fast,it takes about 14ms for its native implementation to do the tests which is almost 4 times faster than Firefox. Obviously we are talking about ms here so it's not going to be as noticeable as the 2500ms of IE6...

YUI is again the fastest of all, followed by jQuery,RightJS and Dojo.
RightJS using the native selector does get the test right this time.
Prototype,Mootools,Ext are not so bad but could gain in speed.

Safari 5 (Win) CSS3 standard selectors

Safari 5 is really fast natively and we basically have the same result as Chrome 6, no surprises here.

As a conclusion for the standard selectors

Amongst all the libraries, Dojo and jQuery stands out as they offer the most reliable engine and speed. Prototype,YUI were very deceptive in IE while Mootools and Ext JS even if a little bit slow does offer some good results in every browsers.