jQuery 3.0 Release Candidate…Released!

Posted on by

Welcome to the Release Candidate for jQuery 3.0! This is the same code we expect to release as the final version of jQuery 3.0 (pending any major bugs or regressions). When released, jQuery 3.0 will become the only version of jQuery. The 1.12 and 2.2 branches will continue to receive critical support patches for a while, but will not get any new features or major revisions. Note that jQuery 3.0 will not support IE6-8. If you need IE6-8 support, you can continue to use the latest 1.12 release.

Despite the 3.0 version number, we anticipate that these releases shouldn’t be too much trouble when it comes to upgrading existing code. Yes, there are a few “breaking changes” that justified the major version bump, but we’re hopeful the breakage doesn’t actually affect that many people.

To assist with upgrading, we have a brand new 3.0 Upgrade Guide. And the jQuery Migrate 3.0-rc plugin will help you to identify compatibility issues in your code. Your feedback on the changes will help us greatly, so please try it out on your existing code and plugins!

You can get the files from the jQuery CDN, or link to them directly:

https://code.jquery.com/jquery-3.0.0-rc1.js

https://code.jquery.com/jquery-3.0.0-rc1.min.js

You can also get the release candidate from npm:

npm install jquery@3.0.0-rc1

In addition, we’ve got the release candidate for jQuery Migrate 3.0. We highly recommend using this to address any issues with breaking changes in jQuery 3.0. You can get those files here:

https://code.jquery.com/jquery-migrate-3.0.0-rc1.js

https://code.jquery.com/jquery-migrate-3.0.0-rc1.min.js

npm install jquery-migrate@3.0.0-rc1

For more information about upgrading your jQuery 1.x and 2.x pages to jQuery 3.0 with the help of jQuery Migrate, see yesterday’s jQuery Migrate blog post.

 

Major changes

Below are just the highlights of the major new features, improvements, and bug fixes in these releases, you can dig into more detail on the 3.0 Upgrade Guide. A complete list of issues fixed is available on our GitHub bug tracker.

jQuery.Deferred is now Promises/A+ compatible

jQuery.Deferred objects have been updated for compatibility with Promises/A+ and ES2015 Promises, verified with the Promises/A+ Compliance Test Suite. This meant we needed some major changes to the .then() method:

  • An exception thrown in a .then() callback now becomes a rejection value. Previously, exceptions bubbled all the way up, aborting callback execution and irreversibly locking both the parent and child Deferred objects.
  • The resolution state of a Deferred created by .then() is now controlled by its callbacks—exceptions become rejection values and non-thenable returns become fulfillment values. Previously, returns from rejection handlers became rejection values.
  • Callbacks are always invoked asynchronously. Previously, they would be called immediately upon binding or resolution, whichever came last.

Consider the following, in which a parent Deferred is rejected and a child callback generates an exception:


var parent = jQuery.Deferred();
var child = parent.then( null, function() {
  return "bar";
});
var callback = function( state ) {
  return function( value ) {
    console.log( state, value );
    throw new Error( "baz" );
  };
};
var grandchildren = [
  child.then( callback( "fulfilled" ), callback( "rejected" ) ),
  child.then( callback( "fulfilled" ), callback( "rejected" ) )
];
parent.reject( "foo" );
console.log( "parent resolved" );

As of jQuery 3.0, this will log “parent resolved” before invoking any callback, each child callback will then log “fulfilled bar”, and the grandchildren will be rejected with Error “baz”. In previous versions, this would log “rejected bar” (the child Deferred having been rejected instead of fulfilled) once and then immediately terminate with uncaught Error “baz” (“parent resolved” not being logged and the grandchildren remaining unresolved).

While caught exceptions had advantages for in-browser debugging, it is far more declarative (i.e. explicit) to handle them with rejection callbacks. Keep in mind that this places the responsibility on you to always add at least one rejection callback when working with promises. Otherwise, any errors will go unnoticed.

Legacy behavior can be recovered by replacing use of .then() with the now-deprecated .pipe() method (which has an identical signature).

We’ve also built a plugin to help in debugging Promises/A+ compatible Deferreds. If you are not seeing enough information about an error on the console to determine its source, check out the jQuery Deferred Reporter Plugin.

jQuery.when has also been updated to accept any thenable object, which includes native Promise objects.

https://github.com/jquery/jquery/issues/1722
https://github.com/jquery/jquery/issues/2102

Added .catch() to Deferreds

The catch() method was added to promise objects as an alias for .then(null, fn).

https://github.com/jquery/jquery/issues/2102

Error cases don’t silently fail

Perhaps in a profound moment you’ve wondered, “What is the offset of a window?” Then you probably realized that is a crazy question – how can a window even have an offset?

In the past, jQuery has sometimes tried to make cases like this return something rather than having them throw errors. In this particular case of asking for the offset of a window, the answer up to now has been { top: 0, left: 0 } With jQuery 3.0, such cases will throw errors so that crazy requests aren’t silently ignored. Please try out this release and see if there is any code out there depending on jQuery to mask problems with invalid inputs.

https://github.com/jquery/jquery/issues/1784

Removed deprecated event aliases

.load, .unload, and .error, deprecated since jQuery 1.8, are no more. Use .on() to register listeners.

https://github.com/jquery/jquery/issues/2286

Animations now use requestAnimationFrame

On platforms that support the requestAnimationFrame API, which is pretty much everywhere but IE9 and Android<4.4, jQuery will now use that API when performing animations. This should result in animations that are smoother and use less CPU time – and save battery as well on mobile devices.

jQuery tried using requestAnimationFrame a few years back but there were serious compatibility issues with existing code so we had to back it out. We think we’ve beaten most of those issues by suspending animations while a browser tab is out of view. Still, any code that depends on animations to always run in nearly real-time is making an unrealistic assumption.

Massive speedups for some jQuery custom selectors

Thanks to some detective work by Paul Irish at Google, we identified some cases where we could skip a bunch of extra work when custom selectors like :visible are used many times in the same document. That particular case is up to 17 times faster now!

Keep in mind that even with this improvement, selectors like :visible and :hidden can be expensive because they depend on the browser to determine whether elements are actually displaying on the page. That may require, in the worst case, a complete recalculation of CSS styles and page layout! While we don’t discourage their use in most cases, we recommend testing your pages to determine if these selectors are causing performance issues.

This change actually made it into 1.12/2.2, but we wanted to reiterate it for jQuery 3.0.

https://github.com/jquery/jquery/issues/2042

As mentioned above, the Upgrade Guide is now available for anyone ready to try out this release. Aside from being helpful in upgrading, it also lists more of the notable changes.

18 thoughts on “jQuery 3.0 Release Candidate…Released!

  1. Nice little update.

    You talked a little bit about the animation update. Will there be, any time soon, an extensive update for jQuery animations?

  2. I’ll right away take hold of your rss as I can not find
    your email subscription hyperlink or e-newsletter service.
    Do you’ve any? Please permit me realize so that I could subscribe.
    Thanks.

  3. Dave on said:

    Anyone got the time to explain that Deferred example in terms someone completely unfamiliar with deferreds can understand, using an example scenario you might actually encounter? I genuinely want to understand it, but don’t.

  4. m_gol on said:

    @Dave the difficulty might come from showing all three changes in one example, perhaps it’d be easier to understand piece by piece. Come to the #jquery IRC channel and ping m_gol and I’ll try to find some time to explain.

  5. m_gol on said:

    @Sebastian We’re thinking about it and will most likely switch from AMD to ES6 modules in the future. No concrete plans for now, though.

  6. Stephane Pericat on said:

    I’m sorry to say this but the $.Deferred implementation is not standardized against ES6 promises:

    catch() is definitely NOT an alias of then()… they handle different scenarios… then() should be invoked whenever Promise.resolve() is called, and catch() whenever Promise.reject() is called…

    As usual with you guys, you can’t just do anything standard (are you ever going to fix $.each() so the value is passed as the first argument and not the index ??)

  7. Timmy Willison on said:

    @”Stephane Pericat”

    First, we did not claim to follow the ES6 Promise spec. We claimed that .then is Promises/A+ compatible, and that is fully tested against the Promises/A+ test suite available on npm.

    Second, we did not claim that .catch() is an alias of .then(). We claimed that .catch(fn) is an alias of .then(null, fn), and that’s exactly what it is (http://www.ecma-international.org/ecma-262/6.0/#sec-promise.prototype.catch).

    Third, your phrasing on then/resolve and catch/reject is not how i would put it, but I can say that both ES6 and Promises/A+ call resolve handlers when a promise is resolved and rejection handlers when a promise is rejected, and that is true of Deferreds as well.

    Finally, no. We are not going to change the argument order of $.each. Usage of $.each is far too widespread to make such a breaking change. Also, keep in mind that $.each was in the wild before it was in a standard. It affected the standard, and that’s a good thing.

    If anything else is unclear, please feel free to ask in the #jquery irc channel or on the jQuery forums (https://forum.jquery.com/).

  8. Bemil Isat on said:

    How about encouraging setting/removing a .hidden CSS class and checking for it instead of having .hide()/.show() and the dreaded :visible selector?

  9. How about encouraging setting/removing a .hidden CSS class and checking for it instead of having .hide()/.show() and the dreaded :visible selector?Are there any current plans to shortly release a corresponding version of jQuery UI to address