$('<div id="foo"><span>bar</span></div>').appendTo('.baz');
I'm not one to condone the over-use of the bloated jQuery, but in this case I sure would.
Anyways, my biggest gripe with this whole thing is the fact that writing any markup in your JS, or anywhere other than an HTML file, is just plain ugly. Beyond that, it's a pain to manage, and totally screws up the whole "separation of duties" paradigm that the web community seems to be quickly forgetting as of late.
Keep your markup where it should be, in your HTML files, because as we all know, HTML is XML and XML is meant to give semantic meaning to data. JavaScript should be a means of transport for data to its relevant structure, not means of giving visual structure to data. Leave that to the HTML and CSS.
Even templating doesn't do it for me 100% of the time and there are better ways. I'm a heavy believer in separation of duties, and any JS programmer should be too. Every time I come across any heavy-handed DOM manipulation in JS I cringe.
As for this article, there's 523637483723526334632 other libraries/frameworks/micro-frameworks that do this same thing, and if you're going to do it, just use what you're already probably using: jQuery. You're probably already abusing it anyways.
P.s. Didn't they mention XSS
Viewmodels let you use the same skeleton structure for different mediums. You can take a viewmodel and generate a native (read "app") interface easily, as long as you have transformations from abstract viewmodel to concrete view. Of course that would require the ability to compile Javascript to native on your platform of choice, but I don't think that is a pipe dream.
The best possible way? Well, that's not true at all. In fact, that was even faster* than whatever method this article was talking about (genDom).
Either way, my point wasn't to say 'just toss it all over to jQuery!' My point was, if you think this technique is cool, you're probably using jQuery and you could've been doing this for years. Years!
Anyhow, this is a huge deflection from what I was really trying to convey. Basically, I don't think this (the 'sugared dom' method from the article) is solving anything. HTML should define your markup and JS should just be filling in the blanks (and not creating them).
*Please note that I do realize my DOM creation was particularly minimal (however, hardly differing from the 'sugared dom' test mentioned in the article) and is hardly a sufficient test. Really, I just wanted to show that you'd have to be doing a ridiculous amount of DOM manipulation to see any significant drop in performance.
I guess this saves you 1ms for every 30 elements you create? I'm sure there are some cases I'm missing where this might make more of an impact, but from my understanding of the article, this looks like a pretty small improvement.
Half of the iPhones ever sold - something like 80 million devices - are pre iPhone 4. There are a lot of low end Android devices on the market _right now_ with worse browser performance than an iPhone 3 (I've got a <6month old Huawei U8110 here as an example). Sure, top-end Android devices compare well against an iPhone4S (I'm pretty impressed with the Galaxy SII I've got here), but the bulk of Android devices in the wild are not late-model-top-end devices.
I had to drop an entire development branch from a project late last year due to insufficient performance of mobile device on-handset ajax. (We fell back to on-server html rendering and innerHTML updates, and even _that_ is annoyingly slow to me on low-end phones.)
And unless you have gathered data showing otherwise, this _probably_ really does apply to you. I was collecting some mobile use data last week - across ~70 websites that I've got Google Analytics access to, the average mobile visits was 14%, and the peak was just over 28%. This was across a range of markets and a variety of levels of "mobile friendliness" of the web design. (Biggest and probably most obvious takeaways from that exercise: B2B sites are a standard deviation or more below average for mobile visits, personal/leisure B2C sites up to one or two SD's above average. 80+% of mobile visits exit on a page with contact details - a phone# or address.)
That being said the speed might actually make a difference with mobile browsers for some applications.
Personally it bugs me. But I'm 31, a total fuddy duddy.
Don't the programing guru's tell us over and over NOT to mix markup into code and vice-versa?
When this heuristic fails, you waste lots of time mangling data to fit it into dumb markup instead of writing a simple loop with a couple of ifs.
And the whole strategy goes down the crapper with NoScript & RequestPolicy for the most part unless I find it worth explicitly allowing them.
The output modes are implemented as plugins, so you can also add other sorts of things, like the template mode I'm in the progress of writing, with template inheritance and the like.
Bretthopper's comment about the readability is spot on, though - you have to start using comma-first pretty quickly or you will go mad getting commas in the right places, and you're never going to get a designer writing these things.
The good thing about it is that since your templates are written in code, it's trivial to share them between client and server - this example app can also be clones and run on Node.js, which uses the same templates to serve full pages when you hit any URL and works as a forms 'n links webapp if you disable JavaScript in your browser: http://jonathan.buchanan153.users.btopenworld.com/sacrum/fra...
You could easily go back and plug in use of a single-letter variable instead of the implicit context object after the fact, but it's nicer to work with while you're building stuff up.
var link = el("a#top.link[src='http://google.com'][data-external='true']")
Instead of: var link = document.createElement('a');
link.setAttribute('id', 'top');
link.setAttribute('class', 'link');
link.setAttribute('src', 'http://google.com');
link.dataset.external = 'true'
Someone needs to bring it to W3C forums, otherwise we might end up with this http://lists.w3.org/Archives/Public/www-dom/2011OctDec/0020....I guess you have the overhead of the template language and rendering them though still.
EDIT: Added links.
HAML and Jade assume that you have static pseudo-markup defined upfront and you just fill it with data, this approach is not suitable for apps that are doing heavy DOM manipulations (e.g. SVG editor, text editor, sophisticated widget toolkit).
http://jsonml.org/ (http://webcache.googleusercontent.com/search?q=cache:http://...)
http://jsonml.org/bst/ (http://webcache.googleusercontent.com/search?q=cache:http://...)
items = [ 1, 2, 3, 4 ]
el 'div#message', [
el 'a.biglink', href: 'http://www.google.com', [ 'A link to Google' ]
el 'ul',
el 'li.item', [ "#{item}. Item" ] for item in items
'There are lots of items'.localise() + '. ' if items.length > 1
'This is just plain text. <script>I have no effect</script>' ]If you run a template once, either to generate a form or a simple list, the DOM is faster than innerHTML.
But if you need to repeat a template(loop), use partials or recurse, interpreted DOM manipulations will become a degree of magnitude slower than a compiled function concatenating strings.
Quickly slow enough to loose the snappy effect of client templating.
You can also use cloneNode to cache frequently reused DOM snippets.
I'm trying for a few months now to remove the last innerHTML bits of pure.js and haven't figured out a way yet to make it as fast.
[1] https://github.com/kriszyp/put-selector
That said, I don't do this very often because the designers I work with prefer templated markup.
Performance benefits seem mostly irrelevant, as pointed out by others.
Personal preference of course, but to me the difference is night and day in terms of my productivity with producing markup.
So I can see there could be productivity gains, but I don't see they would be sufficient to justify the technical debt in introducing a new syntax.