Building a Slimmer jQuery

Posted on by

jQuery is more than five years old now! Over that time it has evolved along with the browsers, web sites, devices, developers, and users that it serves. It has also, um, grown quite a bit over that time. jQuery has added a lot of useful features, but it’s also accumulated cruft that we’d prefer not to support into perpetuity. It may not be an issue on a desktop PC with a high-speed connection, but we want jQuery to be a good solution for mobile devices as well.

Along with our continuing push for higher performance, our priority for upcoming versions is a smaller gzipped file size. It’s hard to do that when every new feature or bug fix must also preserve all existing features and behavior. So today, we want to start a conversation about slimming down the jQuery API by deprecating some features. Here are our guidelines for deprecation:

  • We don’t believe the feature represents current best practice in the use of jQuery.
  • The feature has proven unpopular, confusing, inefficient, or ineffective in actual use.
  • It is not practical or feasible to enhance the feature or address its limitations.
  • Removing it at some future time could yield notable usability, size, or performance benefits.

Deprecation is just the first step in a process that you can participate in. It is our goal to:

  • Explain the reasons for deprecating a particular feature, as described above.
  • Give at least one major-point-version, and often more, between deprecation and removal.
  • Provide alternatives to deprecated features so that migration is not painful.
  • Listen to community feedback regarding deprecation and removal.

Occasionally, as in the situation with event.layerX/layerY in version 1.7, we will make a breaking change with shorter notice if we judge that it will cause less pain to remove the feature immediately than to leave it in. Those will hopefully be rare exceptions.

Version 1.7 Deprecations

With those things in mind, we consider the following features to be deprecated as of version 1.7. Existing code that uses them continues to work, but the recommended alternatives are a better choice for compatibility with future versions.

.live() and .die(): We continue to get many bug reports and see user confusion regarding the quirks of the .live() method. Common issues are now documented on its updated API page. We strongly advise the use of .on() or .delegate() for new code, since they are better APIs. Given its widespread use it’s unlikely we will remove this API in 1.8, but please do update your code as soon as possible.

Non-standard event properties: As part of our push to improve event handler performance, we are also deprecating the copying of several event properties from the native event object to the jQuery event object and will remove them in 1.8: attrChange, attrName, relatedNode, and srcElement. Instead of accessing these through event.NAME you can access them via event.originalEvent.NAME where needed.

$.ajax() Deferred aliases: In version 1.5 we defined .error()/,success()/.complete() on the jqXHR object as aliases for the Deferred’s .fail()/.done()/.always() methods. Although that seemed like a good idea at the time, it makes jqXHR a non-standard Deferred. That’s not good. Whenever possible, use the deferred/promise method name in preference to the jqXHR one. We still have some work to do here to provide a full migration path, so we are likely to continue supporting the aliases past 1.8.

deferred.isResolved() and deferred.isRejected(): Now that Deferreds and Promises have progress notifications and a convenient .state() method, we are deprecating these older methods and will remove them in 1.8. Getting the state of an N-state object using N-1 Boolean methods is a cruel-code version of “Twenty Questions”. Deferred-based code rarely needs to inspect state, and the string returned now is more convenient for a debugging scenario where it’s often used.

.attr(“value”) on inputs: For backwards compatibility, we’ve been returning the current value here (as in “what is currently in the input box”) versus the real attribute (what the value attribute says in the HTML). That leaves us no way to provide the true attribute value, and is confusing since W3C selectors work on the attribute and not the current value. So we are deprecating this behavior and will remove it in 1.8. Always use the .val() method to get the current live value of an input element. Until we can reclaim the attribute, you can use $("selector")[0].getAttribute("value") except on IE 6/7 where that will still return the current value. (Our 1.8 solution will get the attribute value on all browsers and is another reason why we’re anxious to change this.)

.closest(Array) returning Array: This signature is a bit of a strange bird, it was created for use by the old live events code but it returns an Array rather than a jQuery object. As of 1.8 we plan to remove it. The other signatures of .closest() are here to stay and are not affected.

.data(“events”): jQuery stores its event-related data in a data object named (wait for it) events on each element. This is an internal data structure so in 1.8 this will be removed from the user data name space so it won’t conflict with items of the same name. jQuery’s event data can still be accessed via jQuery._data(element, "events") but be aware that this is an internal data structure that is undocumented and should not be modified.

$.sub() as a plugin: Although $.sub() can be useful for creating interference-free zones for plugins, it is not used by jQuery core and not widely used by other code, so we intend to transition it to a plugin in version 1.8 to save space.

Looking Towards jQuery 1.8

Given our push for a svelte jQuery, the filter for new features in 1.8 will be stringent. Even performance-related proposals need to be balanced against the space they use or save. Features that can be implemented via plugins, special events, attribute hooks, or other jQuery extension mechanisms are likely to stay outside core for now.

That brings up the question of what we could deprecate in 1.8 and eventually remove to simplify and streamline the library. Those things don’t have to totally disappear; they could move into a separate plugin, for example, and only be included when needed. Take a look at how you use jQuery, and talk about it with your colleagues.

Within a few weeks, we’ll be opening the call for your ideas concerning jQuery 1.8 with another blog post — so start thinking about it now!

Edit: No, we’re not removing IE6 support yet, and we can’t. As John Resig mentions at every jQuery Conference, most of the sins of IE6 are also visited upon IE7 and IE8, which together still have more than one-third of desktop browser market share. It doesn’t make sense to remove support for IE6 until we can whack IE7 and IE8 as well.

113 thoughts on “Building a Slimmer jQuery

  1. Alistair on said:

    $.browser would be a good candidate for a plugin. It doesn’t appear to be feature complete in core anyway.

  2. Joel Harris on said:

    jQuery is perhaps the only thing supporting the sanity of developers forced to develop for IE6. The best solution, IMO, is to move IE6 functionality into a plugin.

  3. Jens Grochtdreis on said:

    Please consider splitting up the code like jQuery UI and mootools do. I’d like to combine my own flavor of jQuery with all the parts I need and not more. Just like I can do it with modernizr.

  4. Would the authors consider a 2.0 release for the slim-down and method removal? The major version number change should be indicative of a much larger scope of changes, including “Your old stuff won’t work” changes. I just think that kind of thing can get lost in a 1.7 -> 1.8 release.

  5. If you can’t drop IE6 support without also dropping IE7/8 support, how about a flagging that functionality now, and offering up a jQuery version for people who care more about file size than backwards compatibility?

    Assuming that IE 6/7/8 hacks will one day be removed, any work towards flagging them now won’t go to waste.

    You could take it further and allow users to pre-select required browser support, before downloading a custom version. Choose “brand new browsers only” option to get the smallest, fastest version when speed trumps legacy support.

  6. Why not modularize the jQuery core file, so people can customise the function like jQuery UI.

  7. Would be really nice if we could have the options of not including IE 6/7/8 in our build.

    One project I’m working on right now doesn’t support IE 6 or 7, and another doesn’t support 8 either, so there could be some massive savings here.

    I don’t know how far back you support other browsers, but if there’s anything in there for FF3.5 I would prefer to exclude it, and I imagine in a couple months I’ll want to remove anything for 3.6 as well once they “pull the switch”.

    Same goes for really old versions of Safari and Opera.

    Please build an option to remove all of that junk, or at least have someone investigate how much savings it could create, because I imagine it would save a lot of code.

  8. Lea Verou talked about this on her blog. jQuery ‘pure’ I think she called it.

    We should be slimming down the core, not creating spin-off libraries.

    No seedling coder should ever have to make the choice of what jQuery library to use.

    The team should make that decision for him.

    We either embrace modern browsers entirely, or continue to have hangups about old browsers.

    What are your thoughts people, is the separate download a bad idea?

  9. Scott R on said:

    I think it may be time to re-examine the animation API, now that CSS3 is becoming popular in modern browsers. This could easily be put into a plugin for those who still want cross-browser animations, while the rest can use progressively enhanced CSS3 animations in place of Javascript-enabled animations.

  10. Andrew de Andrade on said:

    Please drop IE6 support. Libraries need to leave IE6 behind. Those who are using jQuery 1.7, will now just have to tell their boss or client, “No, we can’t have that feature because we support IE6. If you want to have feature X to make the site better, we’re going to have to abandon supporting IE6.)

    IE6 isn’t going to die until we start hammering nails in its coffin and prepare to put us out of our misery.

  11. Why not stopping IE up to version 7 (or maybe even 8), Firefox up to 3.6, Opera up to 10.6 and Chrome up to 10? Fork jQuery to a legacy and a normal version. jQuery 1.7.x is quite stable, so it would be enough to fix only critical bugs in this release.

    Version 1.8 could be developed for every modern browser. So the only problem will be, what version the plugin writers will support. But if you already thinking about depreciate and remove function this will be a problem anyway in the long run.

    Version 1.8 should have a $.supported method to find out if the browser is modern enough to work. Then the webmaster is able to show a warning or load the legacy (slow) version.

  12. I was also thinking about $.browser. Haven’t used it in two years or so, together with jQuery.boxModel.

    You could also think of removing stuff like $.each, $.map, $.unique, and so on, if it isn’t used heavily inside jQuery core itself. Don’t get me wrong, it’s extremely useful, but you’ve got it double, if you use other libs like underscore.js, and they could be moved to a utility plugin quite easily.

  13. I dream to have an really slimmed jQuery :
    ./configure –no-msie –no-legacy

    And so on for others libs. My services only works for real HTML5 browsers…

  14. Jimmy Headdon on said:

    Have to say I agree fully with Jens here, and the other posters regarding separation of IE6-8 concerned functionality:

    Jens Grochtdreis Says:
    ———————-
    Please consider splitting up the code like jQuery UI and mootools do. I’d like to combine my own flavor of jQuery with all the parts I need and not more. Just like I can do it with modernizr.

  15. Can we start a voting thread with all the current API listed out, then people can start voting on most frequently used api, least used api etc. I think this would give us an idea how everyone are using jQuery. And which feature can be deprecated.

  16. Mathieu Demont on said:

    I second jquery.legacy.js
    a not minified being great, to add some kind of alert, to track down those deprecated use in (my) code

  17. I really like the idea to modularize the jQuery Core like jQuery UI. This will make it easier for both devs and users to support, fix, and use. The result can be a really slim, clean core while all the other stuff _some_ users may need (but not _most_ users) is still available. That means things like IE6 support (personally I’d drop this, but I know IE6 is still widely used) and $.ajax() (I will miss this…). +1 for this!

  18. To people asking to keep support for IE6, keep in mind that if jQuery drops IE6 support, you can still stick to older jQuery versions for IE6. That seems quite acceptable to me. It’s not like your apps will magically stop working because newer versions don’t support IE6. Just don’t update.

  19. T.J. Crowder on said:

    Andrew de Andrade Says:
    <>

    Library support is not why IE6 hasn’t died yet. Removing library support prematurely will only create trouble for those who need to support the large government and corporate users with poor IT departments who still have it (thankfully increasing few of them), and those targeting Chinese users. It will not advance the cause of getting rid of IE6.

    Also note that one of the criteria, quite rightly, is how much space savings removal would generate. I see claims here that it would be “massive,” but if you actually look at the jQuery source, I suspect you’ll find that although it’s pervasive (the odd line or two here and there), in sum it’s not actually all that *big*. And a lot of it may well still be required for IE8 (which will be with us a long time) onward.

    Sadly, that pervasiveness also prevents it being a good candidate for a plug-in. You’d basically have to have a variant instead.

    The things the team seem to be concentrating on, APIs that were poorly-designed and aren’t in widespread use, etc., are probably better targets for short-term gains.

    A year from now the picture may be very different. I certainly hope it is, anyway.

  20. T.J. Crowder on said:

    (Let’s try that again, please delete the earlier copy above. [If you’re going to support HTML tags and require < to be escaped, say so!])

    Andrew de Andrade Says:

    Please drop IE6 support. Libraries need to leave IE6 behind.

    IE6 isn’t going to die until we start hammering nails in its coffin and prepare to put us out of our misery.

    Library support is not why IE6 hasn’t died yet. Removing library support prematurely will only create trouble for those who need to support the large government and corporate users with poor IT departments who still have it (thankfully increasing few of them), and those targeting Chinese users. It will not advance the cause of getting rid of IE6.

    Also note that one of the criteria, quite rightly, is how much space savings removal would generate. I see claims here that it would be “massive,” but if you actually look at the jQuery source, I suspect you’ll find that although it’s pervasive (the odd line or two here and there), in sum it’s not actually all that *big*. And a lot of it may well still be required for IE8 (which will be with us a long time) onward.

    Sadly, that pervasiveness also prevents it being a good candidate for a plug-in. You’d basically have to have a variant instead.

    The things the team seem to be concentrating on, APIs that were poorly-designed and aren’t in widespread use, etc., are probably better targets for short-term gains.

    A year from now the picture may be very different. I certainly hope it is, anyway.

  21. Smart move. I’d been wondering recently when jQuery would start reassessing older contents.

    I want to add support to the call for making this a 2.0 release (perhaps with components choices). It’s a pretty big (potentially) breaking change, not a minor update. I can imagine people getting caught out when they see a new version and updating without consideration.

  22. Hi guys,

    +1 on removing IE6/IE7 support. Whoever requires that should use the older version and not upgrade to the new one.

    Adding CSS3 animations support with graceful degradation, where it makes sense, would be a great improvement to the animations API, as Scott R suggests.

    I am not in favor of following a similar approach to jQuery UI in terms of scripts separation. i think the way jQuery does it right now is perfect. It’s just a framework, not a UI framework consisting of independent entities (widgets) some if which i may not even need in my project.

    I think it makes perfect sense to name this release 2.0 instead of 1.8. Jarrett above has a good point about this. Otherwise devs may get lost in the numbering. It’s already too many new versions of jQuery that got released this year, another one (1.8 ?) wouldn’t seem that different and major.

    Thanks !
    Angel

  23. Another vote for splitting jQuery into modules.

    I started playing with Zepto recently, and realized that almost all of my code works with Zepto, with some changes to account for minor API differences.

    This means that almost all the time I use a pretty small fraction of jQuery’s feature set.

    I can’t really switch to Zepto since it is not designed to support anything other than webkit, but I think that there’s a void for people who want to use the jQuery core but don’t have any interest in the feature creep.

    Many new jQuery features are redundant with things offered by other libraries, or that people have put together on their own, and are happy using. I’m not saying it should not continue to expand, but expand it as modules, not as a requirement.

  24. What about let the user create the ability to choose which functionnality he want on a custom jQuery build?
    Like it is for jQuery UI for instance.

    I already had some projet where I didn’t need at all any ajax feture, but only the DOM parser and animating stuff.

    While you will deprectate functionnality of jQuery, would you create or update a tool like jQuery.Lint to allow developper to be aware of what would disappear soon?

  25. Stephen on said:

    Sadly I understand the need to keep supporting IE6 however on a purely academic note I’d be curious (in regards to mobile) how much weight could be dropped by removing code that specifically supports IE.

    According to my stats, use of IE mobile is not even a blip on my radar… And Win phone 7 IIRC supports IE9 and a respectable level of standards (presuming one is loading only in standards mode).

    As much as I love the diversity of browsers, platforms & devices I’m very happy that IE mobile never succeeded and ruined the baseline for mobile web development…

  26. “Why not modularize the jQuery core file, so people can customise the function like jQuery UI.”

    We need modularize. Nothing else.
    D.

  27. T.J. Crowder on said:

    Stifu Says:

    To people asking to keep support for IE6…Just don’t update.

    Angel Todorov Says:

    Whoever requires [IE6/IE7 support] should use the older version and not upgrade to the new one.

    That doesn’t make any sense. Say a site, for geographic or corporate/government reasons, has to support IE6, perhaps 20% of their visitors are still using it. (I wouldn’t be able to afford to turn my back on 20% of my users, would you? Again, we’re assuming a site aimed at the kinds of government and big corporate installations that still have IE6, or at China where it’s still more than a quarter of general-purpose users.) You’re saying they should be shut out of bugfixes, improvements, and such to jQuery? Relegated to using old tech, because their users insist on doing so? What about the (say) 80% of their users who are using something up-to-date?

    No, that equation doesn’t balance. And again, no one’s provided any metrics indicating that doing so while still supporting IE8+ would result in a significant code size reduction in jQuery, or a significant reduction in effort going forward.

    Someday (soon) we’ll be able to finally wave “bye bye” to these old browsers, perhaps in a year or so on the government/corporate front (I have no knowledge of the Chinese market trend). Meanwhile, the team have plenty of higher-value, lower-downside targets to aim at.

  28. Great initiative! My wishlist:

    – Remove Effects (http://api.jquery.com/category/effects/). This should be a plugin!
    – Remove ALL delegate/bind/live/click/focus/hover/dblclick etc. shortcut methods where on/off methods can be used instead
    – Remove $.browser
    – Keep IE6 support

    I’m also in favour of separate modules. I don’t use Ajax or Forms in every project.

  29. -1 on making jQuery modular. One reason for jQuery’s proliferation is its ability to be accessible from a CDN and improve site performance because of its cache inclusion. By making jQuery modular, sites will no longer benefit from having jQuery in a CDN like Google and fragmenting the versions of jQuery out there. I know there are a lot of features that some people don’t use, but there is a large enough spread that whatever is in jQuery is good for everyone.

    The best solution is just what they are proposing: deprecate from the core and slim it down so that it’s purpose is as close to the needs of developers as possible while keeping it as efficient and maintainable as possible.

  30. I think that the idea to modularize jQuery is the best way. As well, split IE support in a plugin keeping the main code as a framework which only support standard components. Then someone who is going to develop for mobile devices such as iOS or Android could build a custom framework having the opportunity to keep a Web App as slimmer as possible.

    On the other hand, jQuery Mobile would take advantages of this situation.

  31. Honestly, I think while animations used to be an important part of jQuery, thanks to CSS3 transitions they’re much less integral nowadays, and should be separated out into a separate plugin. I never use them, I mostly use jQuery for the query selector and chainability, as well as the various helper methods (.val, .add/remove/hasClass), with all my animations being done through well-timed class management and the now widely-supported CSS3 transitions (and progressive enhancement in old browsers)

  32. Also, I agree with the previous commenter, modularize. I am a former mootools user, and they have this wonderful page that lets you build your own version by just checking boxes (which manage the dependencies automatically) and I would love that in jQuery: I could leave off animations and IE6 support (if that’s even possible) — only problem being the toll that will take on various CDNs and their gracious hosting of jQuery versions (thanks Google!) and the caching benefits of that.

  33. @Eli:
    You can modularize but keep the “full” copy on the various CDNs. Google still hosts mootools, for example. I’d say modularizing would end up with no more than 5 actual “sets” that cover 90% of needs, so CDNs could host those too.

  34. PLEASE don’t kill .live() and .die() – I absolutely love them! Sure, there are other approaches one could take…but I’ve always found them to be an elegant and nifty way to handle all sorts of problems. For anyone doing heavy lifting on the client side, these two are absolutely superb.

    Another suggestion…if you want to reduce size, how about doing a roll your own, like with jQuery UI?

  35. tomgrohl on said:

    Looking through the code I can see these not being needed:

    – $.browser

    – .size method (Can just use length instead?)

    – $.sub (Move to plugin)

    – .get (We can just do $(“#el”)[0] )

    – .live and .die ( .on and .off api would supersede these )

  36. Technically jQuery is modular, it’s just compiled on distribution.

    If your willing to change the distribution model you can begin by providing 2 separate versions of jQuery: with BC and without BC. Internally you pull out deprecated functions into a new source file, maybe deprecated.js, and when jQuery is compiled for deployment you compile one set with deprecated.js and provide that for the general public, and provide one without for those developers who are starting a new project (and thus don’t really have BC issues).