jQuery 1.3 Released
The jQuery team is pleased to release the latest major release of the jQuery JavaScript library! A lot of coding, testing, and documenting has gone in to this release and we’re really quite proud of it.
I want to personally thank Ariel Flesler and Brandon Aaron who put a lot of work into fixing bugs and getting the release out the door.
Overview
There have been a number of major changes in jQuery 1.3, these are a few of the largest and most prominent changes.
Sizzle Selector Engine
jQuery has a brand new CSS selector engine – nicknamed Sizzle. We wanted an engine that was:
- Faster than our current engine for the most commonly used selectors.
- Fully extensible (we had to sacrifice some of our extensibility in favor of performance in past versions of jQuery).
- Completely standalone.
As far as performance is concerned, we’ve done quite well, coming in about 49% faster than our previous engine:
This is especially surprising considering that the engine in 1.2.6 was already pretty fast and that we gained a great deal of extensibility in the process.
One thing that became very obvious during the development of the new engine: We wanted to be able to collaborate on it with other libraries and developers. We saw an opportunity for some solid collaboration with some of the best JavaScript developers – the result of which will help users of all libraries. For this reason we made sure that Sizzle was able to work completely standalone (no dependencies).
Additionally, as a sign of good faith and willingness to collaborate, we’ve released the source code to Sizzle to the Dojo Foundation. We wanted a common meeting ground where everyone would be able to work together and under which there would be a clear long-term copyright holder.
Right now we’re working with Prototype, Dojo, Yahoo UI, MochiKit, and TinyMCE (and many others) on Sizzle, honing it to perfection.
Live Events
jQuery now supports “live events” – events that can be bound to all current – and future – elements. Using event delegation, and a seamless jQuery-style API, the result is both easy to use and very fast.
More information about live events can be found in the .live() documentation.
When working on live events we wanted a solution that was going to be fast and scale well. To do this we needed a selector engine designed to handle delegation element filtering (roughly speaking “does this selector match this element”). The new Sizzle selector engine blew away all of our expectations – coming in almost 30x faster than our previous solution:
By using advanced filtering techniques we’re able to bring you an event delegation solution that won’t bog down your browser and will scale to dozens or hundreds of delegations on a page at a time.
jQuery Event Object
Ariel Flesler brought some serious refactoring of the jQuery event system to jQuery 1.3. The bulk of this change came down to the new jQuery.Event object. This object completely encapsulates all of the functionality normally found in a W3C-compliant event object implementation and makes it work smoothly across all browsers.
There were a number of individual changes related to the event system, as well, and those are described in-depth later on in the event section.
HTML Injection Rewrite
All of the code related to injecting HTML into a document (such as the append, prepend, before, and after methods) has been overhauled. When we were analyzing jQuery applications we found this to be one of the most common bottlenecks – and thus was in direct need for an improvement. The functionality provided is identical to what was in previous releases of jQuery but with the added benefit of being much, much faster (about 6x faster overall):
We also overhauled the creation of DOM elements (e.g. $("<script/>")
) and made it identical to calling $(document.createElement("script"))
(it’s both faster and saner as a result).
Offset Rewrite
Brandon Aaron felt that a full rewrite of the .offset() method was due for 1.3. Re-written from scratch, it not only handles cross-browser issues better, but does so much faster:
Seeing an almost 3x jump in performance over the offset method in 1.2.6 this rewrite is sure to make your complex interactions go that much more smoothly.
No More Browser Sniffing
The final major feature of this release is one that you probably won’t ever see or deal directly with but it’s an important change that’ll help to make jQuery last longer and with less bugs: As of 1.3, jQuery no longer uses any form of browser/userAgent sniffing internally – and is the first major JavaScript library to do so.
Browser sniffing is a technique in which you make assumptions about how a piece of code will work in the future. Generally this means making an assumption that a specific browser bug will always be there – which frequently leads to code breaking when browsers make changes and fix bugs.
Instead we use a technique called feature detection where we simulate a particular browser feature or bug to verify its existence. We’ve encapsulated all the checks that we use in jQuery into a single object: jQuery.support
. More information about it, feature detection, and what this feature provides can be found in the documentation.
It’s important to note that jQuery.browser
is still in jQuery – and will be for the foreseeable future (too many plugins and pieces of code depend on it). That being said we’ve deprecated it in an attempt to encourage you – and all JavaScript developers – to seriously consider using feature detection in your code.
Upgrading
With jQuery 1.3 we attempted to minimize any large upgrade hassles – maintaining all existing public APIs. That being said, please read through the list of potentially-breaking changes to be aware of what might cause problems in your applications.
Note: Many plugins are providing updated releases to coincide with jQuery 1.3. If you’re having difficulties with a particular plugin please be sure to see if a new release has arrived. Specifically both jQuery UI and the Validation plugin have updated releases that work with jQuery 1.3.
Downloading
As usual, we provide two copies of jQuery, one minifed (we now use YUI Compressor as the default minifier) and one uncompressed (for debugging or reading).
http://code.jquery.com/jquery-1.3.min.js jQuery Minified (18kb gzipped)
http://code.jquery.com/jquery-1.3.js jQuery Regular (114kb)
Additionally, Google has provided us with a copy of jQuery hosted on their servers. This copy of jQuery is automatically minified and gzipped – and served from Google’s fast edge cache servers.
http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js
You can feel free to include the above URL directly into your site and you will get the full performance benefits of a quickly-loading jQuery.
Changes
The following are changes that were made that may have a remote possibility to cause backwards compatibility issues in your web pages.
- The ‘@’ in [@attr] has been removed. Deprecated since 1.2 this old syntax no longer works. Simply remove the @ to upgrade.
- Triggered events now bubble up the DOM. Unsuspecting event handlers may accidentally capture more events than they’re expecting.
- The ready() method no longer tries to make any guarantees about waiting for all stylesheets to be loaded. Instead all CSS files should be included before the scripts on the page.
- .isFunction is simpler now, it no longer handles some strange edge cases (in favor of simplicity and performance).
- The order of “a, b, c” style selectors may change. Browsers that support querySelectorAll (Safari, Firefox 3.5+, Opera 10+, IE 8+) will return the elements in document order, other browsers will (currently) return them in the order specified. In 1.3.2 and later release all comma-separated selectors will be returned in document order.
- The trigger and triggerHandler methods no longer accept event objects within the data array. Instead they should be specified directly as an argument.
- The undocumented ‘extra’ function is gone from trigger and triggerHandler functions as well.
- The internal jQuery.event.trigger no longer returns the last item returned by a handler, instead it return true or false as per the W3C specification. You should use a jQuery.Event object to capture the specific return value.
- You should always be sure to run your page in standards mode. There are known issues with methods not working correctly in quirks mode.
- An old (deprecated) style of creating selector plugins has been removed. Previously you could create string-encoded plugins which were later turned into functions – this has been removed – please just create the functions directly.
- jQuery.param(obj) execute obj’s functions instead of converting them to a String.
The following properties have been deprecated (in favor of feature detection and jQuery.support, as discussed in the Overview: jQuery.browser, jQuery.browser.version, jQuery.boxModel.
The following browsers are no longer supported: Safari 2
Performance
To measure the performance of different portions of jQuery we used a modified copy of the SlickSpeed test suite to run our tests (adapted to handle non-selector tests). The raw results for the test runs can be found below (all times in milliseconds).
We used a copy of the Yahoo home page (a representatively complex web page) and used a selection of selectors that people actually use. Targeting selectors that people currently use will help to improve the performance of both existing and future applications.
Frameworks jQuery 1.2.6 jQuery 1.3 Dojo 1.2.3 MooTools 1.2.1 Prototype 1.6.0.3 Firefox 3 184 111 147 240 137 Firefox 3.5 113 34 105 135 55 Safari 3.2 71 15 64 76 50 Safari Nightly 46 15 65 47 18 Opera 9.6 107 75 73 132 87 IE 6 854 640 561 1611 3174 IE 7 210 181 150 490 761 Chrome 30 13 23 118 10
To test delegation filtering we attempted to see if a given element matched a selector. jQuery 1.3 and Prototype provided native methods for handling this (.is and .match, respectively) whereas jQuery 1.2.6, Dojo, and MooTools all used a “run a selector and see if an element is in the results” technique.
Frameworks jQuery 1.2.6 jQuery 1.3 Dojo 1.2.3 MooTools 1.2.1 Prototype 1.6.0.3 Firefox 3 3260 199 1630 3798 763 Firefox 3.5 1047 113 620 1101 298 Safari 3.2 1169 91 820 1223 188 Safari Nightly 911 65 294 590 125 Opera 9.6 1764 167 898 1976 451 IE 6 22142 1201 13000 17227 12827 IE 7 4908 341 2664 5497 2994 Chrome 959 125 700 939 153
These tests analyze the performance of inserting DOM fragments (in the case of jQuery and Prototype this is HTML, for MooTools it was using their Element class). Dojo didn’t provide any explicit helpers for injecting HTML or constructing DOM elements so it was excluded.
Frameworks jQuery 1.2.6 jQuery 1.3 MooTools 1.2.1 Prototype 1.6.0.3 Firefox 3 161 41 47 323 Firefox 3.5 113 31 42 78 Safari 3.2 77 10 25 41 Safari Nightly 87 22 22 31 Opera 9.6 130 23 36 84 IE 6 710 110 600 971 IE 7 560 60 330 460 Chrome 49 14 23 21
Ran the jQuery .offset() method on a number of elements.
Frameworks jQuery 1.2.6 jQuery 1.3 Firefox 3 142 30 Firefox 3.5 45 23 Safari 3.2 92 18 Safari Nightly 75 39 Opera 9.6 39 26 IE 6 151 70 IE 7 100 50 Chrome 115 21
Ran the .hide() and .show() methods on a number of elements.
Frameworks jQuery 1.2.6 jQuery 1.3 Firefox 3 2680 722 Firefox 3.5 1867 448 Safari 3.2 1015 577 Safari Nightly 532 306 Opera 9.6 2327 1173 IE 6 8242 2715 IE 7 1912 961 Chrome 1922 551