YUI3 vs jQuery

JavaScript

Everybody time to time comes to the dilemma which JS library to choose for further development. I used to work with prototype coupled with script.aculo.us and now use YUI3 in the office and jQuery at home. I like both of them, though finding each as the best one ‘sui generis’. YUI3 is a classical framework that provides design patterns and development philosophy as well as tool. jQuery is meant as a rapid, lightweight, flexible and pretty easy to start library. It’s like Ruby on Rails and Python. Ruby and Python as languages are comparable (conceptual elegance against explicit consistency) and you will find APIs of both YUI3 and jQuery are quite similar. Look at this:

// YUI3
Y.Node("ul.example li[rel=tag]").each(function(node, index){
    node.on("click", this._eventHandler, this);
},this);
// jQuery
$("ul.example li[rel=tag]").each($.proxy(function(index, node){
    $(node).bind("click", $.proxy(this._eventHandler, this));
},this));

However if you put Ruby on Rails, you’ll get more. Let’s see what the ‘rails’ for YUI are.

‘YUI on Rails’

YUI Loader

The application built on YUI3 uses API provided by modules. Some of them are modules of YUI library, some added by you. All the modules are pretty isolated, though you can access required components across the modules using Y.Namespace. From the application you access modules through an instance of YUI:

YUI(
    // Configuration for the loader. E.g. location for the additional modules and assets
).use('YUIModule', 'AddedModule', function(Y) {
    //..
});

That is not only about the scope, but also loading modules on demand. So, it allows you have the file structure of source code that reflects the component model of the application. You can compare it to AMD syntax

 define(
        module_id /*optional*/,
        [dependencies] /*optional*/,
        definition function /*function for instantiating the module or object*/
 );

and to EcmaScript 6 syntax:

module $ = require("./library/selector.js");
module CanvasLib = require("http://.../js-modules/canvas.js");
import CanvasLib.{Triangle, rotate};

Widgets

When you are developing a big project, that’s crucial always to know components to deal with, what they are meant for, what they can do and how they related to each other. UML class-diagram would suit to the case.

Static Class Diagram Example

You see, when it concerns UI, most of components are represented visually and have common features. Actually your UI components extend base Widget class and inherits its properties. Besides, component is made ‘in His image and likeness’. You always can recognize the pattern. Component takes configuration as an object. The configuration properties get available as controlled attributes. You can specify to them custom setters, getters, validators, constrains (readOnly, writeOnce) and even more. It reminds of property flags in EcmsScript 5 (writable, enumerable, configurable).

Now let’s see, UI components implement abstract methods renderUI, bindUI and syncUI. The first contains all the logic to render component UI, the second one attaches required DOM event listeners and attribute state change listeners. The third sets up the state of UI according to the current state of component during its rendering.

Widget model

Moreover, rendering logic is well-automated. The idea behind the approach is known as Progressive Enhancement. I would put it in like: UI still stays usable for any browser, even when JavaScript is unavailable. We specify to YUI3 widget where to find markup for the component on a static page. Through HTML_PARSER property components knows of all the partials designed for interactions. So they can be changed dynamically when necessary.

MyWidget.HTML_PARSER = {
    toolbar: 'div.toolbar', // selector finds the div within boundingBox
    itemNodes: ["li.yui3-listitem"], // selector finds node list
    // Set attributes using a parse function. 
    label: function(srcNode) {    
       return srcNode.one("input.title").get("value");
    }
}

You see, that give us additional bonus – we only need one place to specify the markup for component – on the server side. There is no duplication in JavaScript.

Internationalization

YUI allows us to create translation dictionaries (YRB) organized by language, region and category. That can be a JSON-formatted file of .JS extension or YRB-formatted file of .pres extension. They can be included in YUI instance configuration (e.g. which resource in which languages). After that it’s available as objecy of localized strings:

this._strings = Y.Intl.get("greetings");

It supports lookups – when translation token for the target language isn’t found it tries the same token of root language.

Date localization is also presented in YUI. Besides, it has date translations on many languages Module datatype-number is used for number/currency localization.

Find details are at dsheiko.com/weblog/i18n-for-dynamic-ui

Data Source

YUI3 has IO module to communicate data via HTTP like it’s done, for instance, in jQuery or Prototype. But it’s interesting from the maintenance prospective, it has also datasource module which provides unified API to retrieve data from different sources over a variety of supported protocols. It can be combined with other modules to have schema normalization, caching, and polling of data.

Of course YUI covers much more as a framework then highlighted here. I just find those features more significant.

You can find an example of application written by YUI at Addy Osmani’s TodoMVC

Freedom of jQuery

The first what comes on mind thinking of jQuery is easiness of use. You don’t have to learn all that background stuff like in the case of YUI3 or Dojo, for instance. You can proceed to use the JS-programming style you accustomed to, but having amazing tool to do it. That’s very like you have a new version of JavaScript extended by a rich set of DOM-node manipulation API, event-control and AJAX-oriented functions. Do you want your UI to be rapid and lightweight? I doubt you are going to find anything better than jQuery. The whole library has only 27KB compressed size. Can you imagine this?

Besides, jQuery has thousands of plugins enhancing it. It seems as you can find any sort of solution already developed, download and use it in your application.

Method chaining

In fact that’s the matter of technical design. You can make objects chainable by yourself. However in jQuery the principle is spread apparently to any base object.

$("div.test").add("p.quote").addClass("blue").slideDown("slow");

Extensibility

Going further, you can add your own chainable method into jQuery and, I dare to say, it had never been so easy before:

function($) {
   $.fn.myPlugin = function(settings) {
       // element-specific code here
   };
 })(jQuery);

Need to extend existing method? No problem:

$.extend(myWindow.prototype, myWidget.prototype);

You can find an example of application written by jQuery at Addy Osmani’s TodoMVC

Framework

Well, YUI3 has strict and broad architecture for widgets. There is jQuery UI plugin that provides widget abstraction. You can use it to create your widgets. If you want progressive enhancement, you have to design it by yourself. The same, for internationalization and others.

Conclusion

Development under jQuery takes less time and gives really good performance. YUI3 force us to follow predefined coding patterns and provide better maintenance. It’s designed as framework to cover all the aspects of UI development as a holistic system. jQuery has a solid core of basic API, but is meant to extend by mixed plugins.

So I would propose jQuery when the application is not supposed to be a big one. When it’s numerous components with complex dependencies, you rather use YUI3.