jqMobi
Latest Release - jqMobi.com
Version 1.2 - 12/10/2012 - WP8/W8 support

On the differences between JQMobi, JQuery, and Zepto

By Ian Maffet

As was noted in a previous blog post of ours, JQuery has been enormously successful at simplifying the work of JavaScript developers in terms of developing for the desktop Web. We believe it has been so successful it has almost risen to the level of a language unto itself. From that perspective, in the past, we’ve recommended to mobile developers JQuery Mobile and ZeptoJS (a JavaScript framework that attempts to maintain some JQuery syntax compatibility). For various reasons, these great frameworks aren’t ideally suited to iOS and Android. At appMobi, as the name implies, we have a specific obsession with mobile and so we set-out to see what we could do to help our mobile HTML5 developers.

Large Code Size, Faster, Bucket Based (JQuery) 

vs. 

Small Code Size, Slower, Special Objects (Zepto)

I was intrigued with the simpleness of Zepto.js compared to jQuery. The code is smaller, but it does a lot of tricks that make it hard to figure out exactly what’s going on.  This created big performance issues.  Below I’ll outline my dev thoughts and how we differ from these.

First, ZeptoJS uses document.querySelectorAll for all the queries…this makes single selectors perform poorly.  People have made comments about this since the release of Zepto.js.

I saw a few tests on jsperf.com that compared jQuery to Zepto.js.  I was shocked to see that jQuery beat ZeptoJS in every speed test.  After investigating, it was easy to see why.  jQuery operates on a “bucket” level.  Meaning you find everything you want and put it in a big bucket.  Your bucket has all the “magic” to it and you interact with the items inside of it. Zepto.js is the opposite.  Each element acts as a special object that lives together.  Because of this, it creates a bigger footprint in the operations as every element is now a super object that has all the functions to it. Zepto.js uses a lot of recursion and almost always returns a new object with results, rather than working with a master.

Getting to Smallest, Fastest, & Bucket Based (jqMobi)

With jqMobi, we took the jQuery approach of creating buckets to work from.  Our query selector engine respects “#” for single selectors to get faster performance.  On top of this, we do not support non-W3C queries and legacy browsers, so we’re not doing additional work on the objects once we find them.

There are six helper functions from Zepto.js we use (may be a few others that call these…1 liners) 

    function likeArray(obj) {

    ///

    }

    function flatten(array) {

       ///

    }

    function classRE(name) {

///

    }

    $.map = function (elements, callback) {

       ///

    };

    $.each = function (elements, callback) {

       ///

    };

  $.jsonP = function (options) {

       ////

    };

There are a few functions that look similar, but are not copies from ZeptoJS.  I may have used a few lines of logic (or the conceptual idea) in my implementation, but they were written specifically for jqMobi and not copied over.  We also use the concept of creating properties on our object that use the default array functions.  We looked at implementations of functions in jQuery and ZeptoJS (often keeping variable names the same for simplicity to keep track and for developers looking to get involved), but due to how our base “bucket” operates differently, functions required us to write them.

Below is a sample to show the differences.  While our implementations may be larger in size in some instances, the overall design architecture makes us faster.

jQ.Mobi

——

find: function(sel) {

               if (this.length === 0)

                   return undefined;

               var elems = [];               

               for (var i = 0; i < this.length; i++)

               {

                   var tmpElems = $(sel, this[i]);

                   for (var j = 0; j < tmpElems.length; j++)

                   {

                       elems.push(tmpElems[j]);

                   }

               }

              return this.setupOld($(unique(elems))); //sets up the oldParent reference for .end()

           },

ZetpoJS

——

find: function(selector){

      var result;

      if (this.length == 1) result = $$(this[0], selector);

      else result = this.map(function(){ return $$(this, selector) });

      return $(result);

    }

jQ.Ui and jQ.Plugins were all from scratch.  There are some code snippets from Google or the web to do simple loops, or timing functions  I did note we use the viewporter hack from Zynga and acceleration math from iScroll.org because it was a copy/paste/modify based off posts from issues on github.

A look into the very near future

I’m adding more API calls to jqMobi.  One uses a code snippet from John Resig’s blog on looping nodes to get siblings (a simple “for loop” that is 6 lines).

  1. jqmobi posted this