Hacker News new | past | comments | ask | show | jobs | submit login
Vanilla JS, fast, lightweight, cross-platform framework (vanilla-js.com)
208 points by elliotlai on Aug 26, 2012 | hide | past | web | favorite | 125 comments

I can't be the only one getting tired of sites like this making the front page. Really? It would be one thing to see someone write a legitimate article on why they think the move to JS frameworks is harmful and/or the benefits of using plain JS, and for that to make it to the front page. I'd be interested in that perspective. But this is just somebody being snide. It's the internet equivalent of the kid on The Simpsons that points and goes "ha-ha!" There's no content. We can't have a discussion around a smartass joke like this.

Reading the example code I learned enough to become interested in vanilla javascript. Although satirical in tone, I found it insightful. It lead me to question the necessity of using jQuery for every project.

I used to wonder the same thing, but after a while I've found that it already pays to include jQuery (or similar) as soon as your code reaches a complexity of "does more than one kind of thing" (roughly).

How often are you selecting span elements? They serve different purposes. Do you due diligence of course.

If you'll look at the comment below, you'll see a rather interesting discussion going on. Jokes can be an effective way to start a dialogue.

You're right. And now I feel bad that my whiny comment is the top-rated one, edging out that interesting discussion, but oh well. Hopefully I motivated people to prove me wrong. :)

Actually accepting that you had a whiny comment is what's keeping you on top, hehe. Anyways, I felt the same way, oh man another fake library that complaints about frameworks & libraries. It's alright these have to repeat from time to time, not everybody saw the last one, etc.

from time to time, not every other day.

You're not the only one. Considering that the owner have ads on the site, gives evidence of someone who want to make a quick and easy buck from trolling the community.

Fast and lightweight, yes. But vanilla-js is certainly not cross platform ;) You see, that's actually one of the biggest problems with JS and one of the main reasons why people use things like jQuery (apart from the pretty API..).

That cross platform bit is the weakest link sigh.

If you're only targeting modern browsers (latest Chrome/FF/Opera/Safari, IE10), is this still true? I was under the impression the recent browsers were standards-compliant enough that you could use vanilla JS.

Of course, most developers still have to target older browsers, but for a private Web app where you know your target audience, this shouldn't be a huge issue.

There are always quirks, which I assume is what the grandparent is referring to. For example, in WebKit popstate happens on page load, in Firefox it does not. There are many such quirks. Still not worth using a DOM library that will hurt performance, though, in my opinion.

Until Microsoft either discontinues support for Windows XP or releases a modern version of IE for it, libraries like jQuery are all but necessary, in my opinion.

And what's IE10s market percentage? Less than a fraction of a fraction of a percent I bet. And with current reviews of Win8, I don't see that changing in a meaningful way for soooome time.

I think you missed the announcement where Microsoft is going to do a silent update of IE10 to consumer PC's. IE9 usage will drop to the low single digits within a year and IE10 will take its place as the leading IE browser.

How's this going to work for corporate installs? As much as I love the idea of big companies being forced forward, I have the nagging feeling that Microsoft will include a get-out-of-jail-free card for them.

(Speaking as a medium-sized corporation user stuck on Snow Leopard. :] )

The "force" upgrade everyone is talking about is an optional thing. You will be able to go into the settings and turn that off (specifically for corporate use).

IE9 doesn't run on Windows XP. IE10 won't run on Windows Vista. So it's safe to say that even with silent updates (which still won't automatically run on corporate machines with corporate IT policies that control the updates), IE8 and IE9 usage won't rapidly drop into low single digits.

IE8 will probably be more persistent than IE9. I think a lot of corporations are still on XP. Mine is, for example. When companies finally make the jump to Win7, I think they'll move pretty quickly to IE10, so as not to be too far behind. After all, we should expect IE11 next year.

As a note, at my company last year the xp images JUST got IE7. And last week, as the first group of people, our group got upgraded to Win 7+IE8. Major corporations are slooooow at updates.

I'm just happy its happening at all, I know people at banks that have IE6 still.

What about IE8? That's still well above 10% I think.

Depending on where you look, it's at about 14%.


Aren't the polyfills pretty good nowadays?

Yes, but using all of them needed for full HTML5 support in, say, IE6, probably takes up more bandwidth than downloading a new browser.

It doesn't take up any more bandwidth if you're properly concatenating your JS.

Uh, no. I think you misunderstand me.

You're right. That was fairly nonsenical. Not sure what I meant, perhaps I read your comment as referring to requests.

Either way, long-term caching of such shims means the bandwidth to load polyfills only has to be expended once per client. And an extra Mb of bandwidth once per year is a pretty reasonable thing to do for particularly older browsers if it makes your development more sane.

Most people using IE6 are doing so because they can't download a new browser e.g. ActiveX support or lockdown corporate machine.

jQuery API is not pretty

I'll take


  for (var p in document.getElementsByTagName('p')) { p.innerHTML = 'Hello.'; }
any day!

This enumeration is done the wrong way. You enumerate over a DOM node list which looks like an array, which includes enumerable properties like "length". This means that the variable "p" at some point will be "length" and "length".innerHTML = "..." will produce an error.

The proper way is:

for( var i=0, ps=document.getElementsByTagName('p'), len=ps.length; i < len; i++) {ps[i].innerHTML = 'Hello.';}

I'm a JS noob, but I though 'length' was not enumerable (i.e. its 'enumerable' property is set to 'false').

Edit: I think I missed what you said. You're saying it's "like" and array, but unlike arrays its `length` is enumerable. I'll leave my comment so other skeptics can benefit :)

Edit2: This is what I was referring to (read the 'Note' at the right side): http://bonsaiden.github.com/JavaScript-Garden/#object.forinl...

Looks like this is correct:

paras = document.getElementsByTagName('p') for (var para in paras) { console.log(para)} 0 1 ... 9 10 length item

That's ES3. You have no reason to choose that way anymore - ES5 loops work everywhere current, can be polyfilled into IE8, and don't require any boilerplate stuff.

var paragraphs = document.getElementsByTagName('p');

paragraphs.forEach(function(paragraph){paragraph.innerHTML = 'Hello.';})

This will not work - Check my solution below :)

document.getElementsByTagName returns a DOM Node List and it does not have forEach method according to the DOM spec. DOm Nodes, Elements and Node Lists and Node Maps do not follow the javascript spec (ECMAScript) hence do not share methdos and properties. A Dom Node List does not have the methods of the javascript array. That is because DOM Node List does not inherit from the Array.prototype, because it is not javascript - it has its own spec that exactly determines what methods and properties it should have. The implementation in the browser happens to be accessible through javascript but that does not mean that the DOM is part of javascript. That is why wrapper libraries like jQuery or other abstractions are necessary to make the DOM much more accessible from a JS perspective. BTW that is why many people confuse DOM with javascript and then get frustrated which is understandable.

Except #forEach is a method of Array, and getElementsByTagName does not return an Array but a NodeList. Which doesn't have any of Array's methods (it has a length, it can be indexed, and it has an alternative indexation method - #item — but it's not an array at all)

You're right. I wasn't sure earlier, as I was typing on a phone with no JS console.

but never mind:

Array.forEach.call(paragraphs, function(paragraph){paragraph.innerHTML = 'Hello.';})

will work fine.

Ah, thanks for the correction! I just wrote it out from memory, and it's been a while since I used Vanilla-JS DOM selectors ;)

Try this in a browser. On Webkit at least is also returns length and item:

for (var p in document.getElementsByTagName('p')) {console.log(p);}

The jquery version is easier to write, and less prone to error, but in the native version it's much more clear what's actually going on.

Also in the native version, you know you're only doing the work required. The jquery one will be doing a lot of extra useless inefficient grunt work to achieve nothing. Making it incredibly slow in comparison.

Premature optimization, and all that. It is trivial to get raw dom nodes out of jQuery, so you can easily use jQuery to begin with and replace any code with the full DOM API calls should it every become a performance issue.

This discussion is a bit like how assembly programmers used to defend not moving to a high level language long after the performance benefits were not worth it any more.

> This discussion is a bit like how assembly programmers used to defend not moving to a high level language long after the performance benefits were not worth it any more.

But we're not at that point in the web yet. The performance benefits are worth it. Just try out JQuery Mobile if you want to see what wasted CPU cycles can do.

It may be worth it for specific use cases, just like there are certainly still specific use cases where assembly shines.

The point is we're well past the point where grasping for the asm-equivalent from the start should be the default unless you happen to specifically target one of those niches.

Mobile isn't a niche.

That depends on the application.

It depends on what you're trying to do. Mostly, I try to write code that displays the same in every possible browser without special-casing or using confusing idioms. CPU cycles are cheap. A webpage that loads a little slow is a possible lost sale. A webpage that fails to load is a definite lost sale.

> It is trivial to get raw dom nodes out of jQuery, so you can easily use jQuery to begin with and replace any code with the full DOM API calls should it every become a performance issue.

That's still going to be a lot of work if the performance issues turn out to be many separate jQuery calls spread all over your code, which is not unlikely.

The jquery one will be doing a lot of extra useless inefficient grunt work

Such as?

"Useless" is subjective, but the jQuery object does a lot of extra work above the vanilla example.

$ isn't just a syntax layer on top of querySelectorAll. When you do $('p'), it first queries the DOM for everything that matches that selector, then it creates new jQuery objects to wrap each of the returned nodes as well as creating a jQuery object to contain them.

If all you're doing is setting the innerHTML of these objects, it's a non-trivial overhead.

It creates just one jQuery object to wrap the entire array of DOM nodes. Afterwards, .html() is essentially innerHTML [1], provided jQuery can use it directly (otherwise it has to create DOM nodes by itself).

[1] https://github.com/jquery/jquery/blob/master/src/manipulatio...

>but in the native version it's much more clear what's actually going on.

Yes, but it's also more probable that it won't go on at all (due to browser incompatibilities and such).

did you ever try to debug your pretty jquery karate?

ps. second example is not valid, in Vanilla JS you do it like this:

  document.getElementsByTagName('p').filter(function(el) {
    el.innerHTML = 'Hello.';

The right way is this :)

Array.prototype.forEach.call(document.getElementsByTagName('p'), function(el) { el.innerHTML = 'Hello.'; });

I like how the end of that statement contains both a winking crooked-smile smiley next to black-eyed frown smiley.


TypeError: document.getElementsByTagName("p").filter is not a function

Because you don't get an array, only something array-like.

And this discussion over how to write a trivial loop is why I stay far away from vanilla js unless performance absolutely forces me to optimize.

This is why I program with a code editor / interactive console that tells me these things as I'm typing :-)

I'll take $(node).remove() over node.parentNode.removeChild(node) any day.

innerHTML is an easy one, try setting an attribute -- you have to create a new attribute node, set its value and then add that to the element..

> you have to create a new attribute node, set its value and then add that to the element..

Erm... no you don't: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-F68F082

You should set the node property instead (e.g. standard textContent or innerText). It will work everywhere.


IE8 =(

I am a c developer, now I want to learn jQuery , but its syntax seems so weird to me, Vanilla JS looks more comfortable to me , one questions, does it supported by webkit?

I'm sorry. I don't know if you're joking or are serious. But if you're a C programmer and have no experience with JS I guess it must be really easy to be fooled by this "joke".

Some JS people (the ones usually with a long beard) hate how kids use frameworks like jQuery and this site is an attempt at telling them "The vanilla JS, i.e. the standard language that all browsers use and your cool jQuery leverage under the hood, is quite capable these days. Use it". They are not quite right, but aren't quite wrong either (IMO). You'll be a dreadful JS programmer if you only know jQuery. JS is sooo different from C (and Java) that if you don't know the core language everything you'll do will be wrong. For starter: there's no block scope. Only function scope.

Every JS programmer should read "JavaScript: The Good Parts" by Douglas Crockford cover to cover - before learning jQuery.

there's no block scope. Only function scope.

There is global scope as well, and it's (unfortunately in most cases) the default.

Also there is block scope. let { ... }

AFAIK, let is a Mozilla only feature.

I want to learn something about jQuery,because recently I need to develop an application which use webkit. It has a feature that need to highlight some special words. After search in the internet, I found the jQuery can 'easily' do that. But the syntax of jQuery make me headache, then I happened to see this article. Thank you very much , I am very appreciate for your advice:)

Look at other libraries. I cant beat the MooTools drum loud enough.

Compared to the dom api, it is very pretty.

This site could actually be made useful if the little area where you check which "features" you want to include that "generated" the download file actually caused cross-platform, native JavaScript examples of those bits of functionality to be included in a real downloadable file.

If you really think more people should be using plain vanilla JavaScript (and in a lot of places, I think this is actually true and even when a framework is needed, it's good to have the underlying skill) then the way to get them to do that is to educate them on it, not patronize.

Raw Javascript is simply not an option. The API is awful, default types are not powerful enough and cross-platform consistency is a joke. For every decently sized project you start in JS you have to reinvent a thousand wheels to even get rolling, so you better just leverage a framework.

Wow, even jQuery is written using vanilla-js.

Does anyone else find the code examples absolutely damning?

Aside from not being cross-platform, VanillaJS is just plain ugly.

Recently, I was interviewing a front-end developer candidate and I gave them a simple JavaScript problem. The sad thing was, they didn't recognize `document.getElementById()` and didn't know any of the parameters to `addEventListener()`.

We finished the exercise assuming the example used jQuery instead.

That's a fair assumption since most of front-end development is done using jQuery as far as the DOM goes.

Did you expect your interviewees to have memorized APIs? There's Google so that you can look up those when needed.

Not recognising document.getElementId is pretty bad, though. It's perhaps the most basic and commonly used part of the DOM itself.

I agree. I think it's important to know Javascript as a language well, but there are very few cases when you'd be using Javascript without some abstraction from the DOM.

And in point of fact, neither of those examples are actually about JS, the language. They're about the DOM.

It's a common problem nowadays I guess. I honestly don't remember the last time I worked on a project with plainjane javascript.

There always is either underscore or backbone or require or dojo or prototype or yui or jquery...

Don't really know if this is good or bad!

maybe I'm mistaken, but I think this is more of "jquery programmer" problem. jQ really abstracts away from the nitty gritty of the dom api and also for any beginner / intermediate frontend guys the source is not very readable. In comparison dojo for example, requires you know what you're doing and also to have pretty extensive knowledge about js, the dom, etc. Also, in my opinion, its source code is very clean in comparison.

Was anyone else surprised by the performance penalty of jQuery? Over 400x hit for getElementsByTagName! I'm curious whether this is more due to cross browser checks or determining the what type of selector was used. To the source!

> Was anyone else surprised by the performance penalty of jQuery? Over 400x hit for getElementsByTagName!

Not really. Just replacing document.getElementsByTagName by document.querySelectorAll (the native, browser-implemented version of what jQuery does) will generate a 150-200x perf hit depending on the browser.

The reason for that is twofold: first, getElementsByTagName doesn't have to parse the selector, figure out what is asked for, and potentially fall back on explicit JS implementation (jQuery supports non-native selectors. In fact, I believe you can implement your own selectors). But the parsing overhead should be minor in this precise case.

Second, the real reason for the difference, getElementsByTagName cheats something fierce: it doesn't return an Array like everybody else, it returns a NodeList. And the nodelist is lazy, it won't do anything before it needs to. Essentially, just calling document.getElementsByTagName is the same as calling an empty function. If you serialize the nodelist to an array (using Array.prototype.slice.call), bam 150~200x perf hit.

See http://jsperf.com/vanillajs-by-tag/2 for these two alterations added to the original "vanilla JS" perf cases.

There is a significant overhead to jQuery, but it's ~3x compared to the equivalent DOM behavior, not 400x.

I suspect the benchmark is flawed, and charging jQuery for one-time penalties for every function. i.e., if you make a page that has nothing but a getElementById call, vs. loading jQuery and executing the query on the DOM, it's obviously going to be a lot slower. Even if that's not the case, "fast enough" is fast enough...and jQuery has proven itself to be fast enough for a lot of stuff. And, most developers working in JavaScript and building their own helper libraries and such are extremely likely to make worse libraries than jQuery. So, it's probably smarter to use a library that's getting a lot of vetting by really smart people. Whether it's jQuery or something else, I'm not gonna go back to hand-written JavaScript (I'm in the midst of converting an app to use jQuery from handwritten functions, and the new version is either faster or similarly fast, and maintenance of the frontend is getting vastly simpler with every element that gets converted from the handwritten functions to jQuery+Bootstrap...hell, sometimes, I'm able to just use markup with no JavaScript on the page at all...and that's like magic).

It may just be illustrating the problems with micro-benchmarks.

http://vaporjs.com/ is way better, and was here first.

I prefer semicolon.js, more secure and reliable :) https://github.com/madrobby/semicolon.js

Actually, function.js is vastly superior as readers of "JavaScript: The Good Parts" will know: https://github.com/TazeTSchnitzel/function.js

There is an error in the Readme. It begins with "Vapor.js is a much more...". Should be "Function.js is...".

I don't know... It has no tests, no generators, no ports. Not that realiable to me. :)

doesn't minify or gzip at all - talk about code golf. does it lint?

Question: is the 'Speed Comparison' for real? I find it really, really hard to believe. Surely jQuery & co. revert to native implementations (if they exists, as they do in all modern browsers) for things like `document.getElementById` and don't iterate over the whole DOM.

> is the 'Speed Comparison' for real?

Depends what you mean by "for real". The document.getElementsByTagName comparison is bullshit: gEBTN is lazy, just calling it basically doesn't do any work, it just allocates a NodeList object and returns.

If you serialize the nodelist to an array or use document.querySelector instead (it returns an array) you get ~3x between the native version and the slowest libraries, not 400x.

Yeah, Sizzle will grab an element using `document.getElementById()` but only after checking the nodeType of the context, ensuring the selector is a string and running the selector through a regular expression.

I just looked at the latest jquery and its each statement does not do a native fallback, which really surprised me. Also you have to keep in mind that a simple $('a.active').each(someFunc), has to run through the a lot of jq luggage, plus the initial http fetch of the library (which has come under criticism for its size).

Not sure why Vanilla JS doesn't require <script> tags, whereas jQuery apparently does.

Both require it. Its just a marketing ploy to improve the aesthetics of Vanilla JS.

I love pure JavaScript. jQuery is overrated and most libraries are only good for one thing or the other, nothing can replace the joy and performance of Vanilla JS!

If you listen to HN a lot you'll believe everyone uses jQuery or some other framework, but that's not true. I use vanilla JS and I love it!

jQuery is kind of a big download for mobile, so I often skip it for small tasks.

What gets me is when people include jQuery and then further bog things down by loading a lot of plug-ins to do things that could easily be accomplished by adding a few lines of code of their own. Even if you do need and include jQuery, it doesn't mean you have to use it for every piece of javascript in your app.

Many times, a plug-in will do a lot more than you need it to do. If your primary goal is to just get rid of the 300sm delay translating tap events to click events, you don't need a library for full gesture support. You need half a dozen lines to listen for touch events.

If you just need to add some client-side persistence for a few basic things in LocalStorage, you probably don't need a plug-in with a complex query syntax.

Cannibalize a library if you need to and pull out the bits you need. You don't have to include the whole kitchen sink.

> jQuery is kind of a big download for mobile, so I often skip it for small tasks.

That's what Zepto[0] is for: jQuery's API, 20% of the size (although it drops some features, e.g. $(selector) is pretty directly proxied to document.querySelectorAll, so $('> .foo') works in jQuery but blows up in Zepto)

[0] http://zeptojs.com/

Ah, last I looked at Zepto, it's support for non-webkit browsers was pretty lacking. It's good to see they're making strides on the cross-platform comparability front. The supported browsers list looks pretty good now.

Been using it on mobile for about a year. It's small and snappy, and the people behind it are very responsive & opinionated in a good way.

these sites are getting really old

The features generator is a nice touch.

I would have liked a compatibility chart between this and the other frameworks.

All the others rely on this one, so it wouldn't be a very fair chart.

$.ajax({ type: 'POST', url: "path/to/api", data: "banana=yellow", success: function (data) { alert("Success: " + data); }, });

can be written as

jQuery.post('path/to/api',{banana:yellow},function(data){alert("Success: "+data);});

much simpler and easy than

var r = new XMLHttpRequest(); r.open("POST", "path/to/api", true); r.onreadystatechange = function () { if (r.readyState != 4 || r.status != 200) return; alert("Success: " + r.responseText); }; r.send("banana=yellow");

nevermind got the joke. but i think jQuery helps write faster code sometimes

wow, the list of the companies using vanilla.js is impressive. if those put their trust in this framework, it surely must be good.

It confuses me if you describe a JS framework as cross platform. Isn't that the whole point of using JS?

The first book listed on the "Books" link is: JavaScript & jQuery: The Missing Manual


Given how optimized jquery is, does anyone understand why something as simple as getting an element by id would be so much slower than Dom methods?

I'm surprised by the number of comments like this.

jQuery has to parse the selector and figure out that it's of the form "#id". This requires running a regular expression. A lot more is happening.

The whole jQuery call from start to finish takes 2.85 microseconds, in what is presumably a real benchmark, but microbenchmarks like this are hard to interpret and basically meaningless. But yes, if your app needs to do a burst of 350,000 jQuery calls in a tight loop and you are bummed that the whole thing takes a full second, you should then optimize using document.getElementById.

> I'm surprised by the number of comments like this.

The sentiment is borne out by the facts when you dig a little deeper. Just calling document.getElementById without using the return value does not actually dig into the DOM and find the element according to this comment: http://news.ycombinator.com/item?id=4436438

> if your app needs to do a burst of 350,000 jQuery calls in a tight loop and you are bummed that the whole thing takes a full second, you should then optimize using document.getElementById

Seems like you might have some other optimization work to do at that point :)

Get back to me when Vanilla.js has a way to handle document ready, and then I'll believe that it's cross-platform.

If nothing else, the word doc look is pretty amusing :)

I want to use vanilla.js, do you think I should minify it and serve with gzip compression? Anyone know if it will pass JSLint?

nope you have to use codesmell jquery and backbone :p


ANYWAY, Lol at that... made me chuckle.

Haters gonna hate.

So many JS frameworks, so little time...

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact