Zumi's Scratchpad

(Moved) Elementals.js, and comparison between similar libraries

I try out some helper Javascript libraries.

TODO: Add comparison graphs and files

Elementals

Tonight I learned to use Elementals.js and take advantage of one of its more advanced features - generating elements programmatically through JSON - or as the author calls it - DOM-JON.

Definitely prettier than using innerHTML, which people do on jQuery all the time apparently, and looks nice as a standard templating thing.

I can definitely make reusable components out of it...

Relevant snippet - EJS:


newCard = _.make('article.card.card-fade', {
content : [
[ 'header',[
[ 'time.x-when',
{ timedate: date, content: date }
]
]
],

      [ 'h3.node-title',
          title
      ],

      [ 'footer',[
          [ '.x-author', author ],
          [ '.x-upvotes', votecount ]
        ]
      ],
    ],
    last : document.getElementById('gallery')
  });

Sources:

Comparison

UmbrellaJS has this: var link = u('<a>').addClass('main').attr({ href: '/hello' });

but EJS looks more concise...

So does BlissfulJS: var element = $.create([tag,] [options]); almost the same syntax!

This afternoon, I ran a benchmark of some JS libraries (BlissJS, ElementalsJS, jQuery) against vanilla JS.

To run the benchmark, I used benchmark.js. Unfortunately, it pulls lodash, and to visualize it, I used Chart.js. I feel a little dirty. Not only that, lodash's helper object also uses _ as its' name. Elementals' codebase is more comprehensible to me so I chose to change its _ object to "Elementals".

First benchmark compares getting DOM by ID, and getting its html as well as text.

Elementals placed 2nd to Vanilla (Bliss follows) except for getting text.

For getting text, Elementals places dead last, performing worse than even jQ. I think this is because Elementals' text function isn't just an innerText - it normalizes it through stripping spaces. Changing methods for getting the target DOM for this (Elemental / native) doesn't raise the odds, either.

Using textContent for Elementals' getText test brings it up to speed, though.

Benchmark on making a DOM node has Elementals (~200K o/s) behind Bliss (~330K o/s). Comparable seeing as it has a very similar format.

Trial:

Operations per second:

Relevant library code:

Bliss:


create: function(tag, o) {
if (tag instanceof Node) {
return $.set(tag, o);
}

// 4 signatures: (tag, o), (tag), (o), ()
if (arguments.length === 1) {
if ($.type(tag) === "string") {
o = {};
} else {
o = tag;
tag = o.tag;
o = $.extend({}, o, function(property) {
return property !== "tag";
});
}
}
return $.set(document.createElement(tag || "div"), o);
}


Relevant Elementals code is even too big to fit - it's a whole factory compared to Bliss' approach. Cross-browser compatibility may be a factor in Elementals. Has legacy browser checks for namespaced elements.

Bliss' maker function simply returns a createElement + setting attributes - in this case setting textContent directly. In other words it's just tapping vanilla JS more directly than Elementals, so that might explain the speedup. Relevant Bliss set code:


$.Element.prototype = {
set: overload(function(property, value) {
if (property in $.setProps) {
$.setProps[property].call(this, value);
}
else if (property in this) {
this[property] = value;
}
else {
this.setAttribute(property, value);
}

}, 0),


Elementals uses internal function _.Node.write, for inserting createTextNodes or existing elements. Could be an additional bottleneck.