Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Going Simple with JavaScript (snook.ca)
103 points by joshuacc on March 5, 2012 | hide | past | favorite | 69 comments


For those interested in something more lightweight than jQuery that supports the majority of commonly used functionality, give Zepto a try.

http://zeptojs.com/

It has a compatible syntax at a third of the weight. It's very well suited to mobile.

With regards to the original post; it's fantastic to be doing things efficiently, but in the vast majority of circumstances I would presume that forcing the user's browser to download some additional kb of libraries is preferable to forcing the user to Google a currency conversion.


As this article points out, we're past the point where we need frameworks for small/medium projects. Animation is now handled by CSS3. JavaScript has been updated in all major browsers and now supports bind/each/map/filter right out of the box.

If you're starting now, you can build effectively in JavaScript alone. That said, you may still benefit from a framework if you're doing a very large, long-term project.


Yes, Javascript the language is getting better support in browsers, but DOM manipulation without a framework (like jQuery) is still horrible.


That's completely contrary to what I've experienced. Only browsers that "need" a little extra JS/CSS are the old IE versions. Quotes indicate you don't necessarily need to enhance pages in those browsers at all these days.

If your experiences indicate otherwise, you are simply doing something wrong.

PS. jQuery is horrible. Every time you think you've figured out all of their undocumented quirks, they change the logic. It's famously inept in IE 6/7.


JavaScript has been updated in all major browsers and now supports bind/each/map/filter right out of the box.

No version of Safari supports bind.


It's interesting to me since I started out in the days before jquery and had to force myself to learn these new libraries. I have started to notice a new generation coming up that think jquery is required to do any work.

I will say though, it sure is nice not having to deal with all of the browser weirdness that you face without a lib like jquery.


I think the point is that learning how to program around all the browser quirks is such a monumental waste of effort and time. So in reality i'd say jquery (or any other lib like it that smooths out inconsistencies) is required. Unless you enjoy pain or have something to prove :)


What I'd really like is something that fixes browser quirks and provides a consistent API that's identical to the ecmascript standard, instead of something entirely new.

Then have a jQuery-like API when it's useful or improves clarity.


You're talking about polyfills. This is increasingly the way to do quirk-normalization. One example of the Function.prototype.bind polyfill on MDN: https://developer.mozilla.org/en/JavaScript/Reference/Global....


Nitpick: you probably mean the HTML/HTML5 DOM API, because the ECMAscript standard only regulates the language, not the host (a.k.a. browser). There are small differences in how browsers run JavaScript or what version of JavaScript they run, but those are much less painful to deal with than DOM API and other API quirks.


Change your goal to something other than "learning how to program around all of the browser quirks". Why would you need to do such a thing?

And if you "enjoy" jQuery, you have no frame of reference. It's far more inconsistent than the DOM implementations and the documentation is terrible.


>I think the point is that learning how to program around all the browser quirks is such a monumental waste of effort and time.

What quirks is jquery saving you from dealing with? There are some, but I'd like the reader to actually think about this for a moment.

Many simply defer to jquery now and have lost curiosity about the underlying browsers (which have been rapidly improving).


you're kidding right? Off the top of my head event normalization is worth its weight in gold.

Oh and try querying for something like this in ie6.

'.class + .other_class > .yet_another_class'

Having css3 query support in legacy browsers is awesome.

Not to mention productivity gains from method chaining and batch assignment such as

$('.somehting').find('*').css({'font-weight': 'bold'});

Do you really want to type the 10-20 lines of JS that are required to make that happen? I don't.


The DOM is not CSS. Please realize this. Your monstrosity of a query illustrates a continued ignorance of the DOM.

"event normalization" is another "nice-to-have" that isn't necessary. DOM 0 event handlers (e.g. `node.onclick`) have worked for decades. Each node may only be allowed one handler, but there's more than enough nodes to get the job done. Of course, event delegation can be used to handle more than one event, so this becomes moot.

I can guarantee you that the frivolous "productivity" gains from chaining Frankenstein queries like yours are mitigated by massive speed losses from parsing.


you're kidding me right? Obviously you filter your queries to the closest node. Are you testing your code on ie6 running on a 486? Even a 486 could parse out a handful of nodes from a dom sub tree in max double digit milliseconds.

Those 'Frankenstein' queries are ridiculously easy to read and to type.

'massive speed losses from parsing'

Nobody is searching the entire dom for matching nodes.

The single biggest performance killer... far more important than tree traversal is event overhead. As long as you think long and hard before applying a new event handler (and use delegation whenever possible) you'll be fine even with those 'Frankenstein' queries hehe :P

The DOM is not CSS.

What does that even mean in this context?? How does it further your point?

illustrates a continued ignorance of the DOM

enlighten us then...


> Are you testing your code on ie6 running on a 486?

I test all the way back to IE 5.5. Try browsing a site with a heavy jQuery dependency in IE 5.5 (StackOverflow is a nice example). Those sites tend to implode.

> Those 'Frankenstein' queries are ridiculously easy to read and to type.

You sure about that?

A: `$(someForm).find("input[name=whatever]")`;

B: `someForm.elements.whatever`;

B is quicker to execute, type, and read.

Try running some speed tests on `find`. You'll notice it's pretty inefficient.

> Nobody is searching the entire dom for matching nodes.

I should start counting the number of times I encounter `$(".stupid")` reading source code. The count would probably be in the thousands.

> What does that even mean in this context?? How does it further your point?

Using "CSS selectors" to traverse a tree of nodes is utterly stupid. That's what recursion/tree traversal algorithms are for. What's nice is tree traversal is rarely necessary. Selecting via `id` or `name` (through an `HTMLCollection`) is quick and easy.

> enlighten us then...

I've posted 3 comments now on this topic. Shall I link various DOM specs?


Using "CSS selectors" to traverse a tree of nodes is utterly stupid.

Clearly your opinions differ from the majority of the web community.

Why do you think we now have document.querySelectorAll?

Have a look at the mdn article: https://developer.mozilla.org/en/DOM/Document.querySelectorA...

example given on that page: var matches = document.querySelectorAll("div.note, div.alert");

also :

http://www.w3.org/TR/selectors-api/

Makes perfect sense.

That's what recursion/tree traversal algorithms are for

No. That's what highly optimized browser internals are for.

I test all the way back to IE 5.5

Why? ie5.5 is 12 years old.


> Clearly your opinions differ from the majority of the web community.

> Why do you think we now have document.querySelectorAll?

This is called "argumentum ad populum" (appeal to popularity). The advent of jQuery caused clueless "developers" (along with library authors) to beg for "native" selectors. QS(A) is the result. They were never needed in the first place.

> Why? ie5.5 is 12 years old.

Internet Explorer's Quirks Mode (which still exists in IE 9) is a simulation of IE 5. It's useful for testing against IE's old box model.


Right and you have to test at least one browser that ranks below your expectations, else you wouldn't know if your feature detection/testing was working.

Granted, the typical Web developer will simply announce they don't care about any browsers deemed inferior (or unknown to them) at the time. History has shown that such carelessness leads to sites that are more likely to break in future (unknown to them at the time of development) browsers.

Often the expected outcome for IE 5 is a static page.


caused clueless "developers" (along with library authors) to beg for "native" selectors.

ahh now I get it. you're one of those guys. you're just smarter than everyone else right? good luck with that.


Nooo... you don't.

You are one of those guys that figures anything popular must be smart. Good luck with that. :)


would you please edit/update your non-response to be less useless.


> you're kidding me right? Obviously you filter your queries to the closest node.

You again. Smart-ass doesn't suit you.

Obviously, you can use standard DOM methods (e.g. gEBTN, gEBCN) with the "closest node" as well.

And, assuming you mean an element node, you just bought yourself a world of hurt. jQuery and the like will use the Selectors API (e.g. QSA) when it suits them, and due to their disagreement with the specs, element nodes don't suit them.

When they use their own query code, performance and compatibility go right down the toilet.

In other words, use QSA with the document node, unless you want to relearn how queries work.

> The single biggest performance killer... far more important than tree traversal is event overhead. As long as you think long and hard before applying a new event handler (and use delegation whenever possible) you'll be fine even with those 'Frankenstein' queries hehe :P

Again, event delegation is unrelated to queries. It's silly to assume you can use wasteful queries with impunity as long as you don't attach too many listeners.

And yeah, those "Frankenstein queries" are the exact opposite of self-documenting code (something jQuery proponents get backwards).


IE6 is below 5% market share. But if you absolutely have to support IE6, then yeah, use JQuery.

There are still some differences in modern browsers but those can mostly be repaired with polyfills.

Oh, and while I would not recommend doing your chaining operation (chaining just makes it harder to debug), I can write the same thing in one line of JavaScript:

      Array.prototype.slice.call(document.querySelectorAll('.something > *')).forEach(function(el) { el.className += ' bold-font'; });


Yeah sorry that one liner is pretty ugly. Also I don't see the issues with chaining and debugging. Chrome has a v.good debugger. And to top it off querySelectorAll requires ie8+.

Why not just use a extremely well tested library that automatically gives you full browser support? All for the equivalent price of one very small jpeg file.


> Why not just use a extremely well tested library that automatically gives you full browser support?

LOL. Which library would that be?


hehe just came back to check my comment history... dude u really created what 3.. 4? different accounts to reply to my messages?? Lol i really got under your skin. you are familiar with this right?

http://www.flickr.com/photos/villagemember/987251565/


Yeah sorry that one liner is pretty ugly

You had said that it was 10 - 20 lines of code. The reason I posted my original comment is that many jquery abusers don't know about alternatives.

Why not just use a extremely well tested library that automatically gives you full browser support?

You have to justify why you use something additive, not why not to use it.

All for the equivalent price of one very small script file.

Not quite sure why the load time of the script file gets so much attention. It is hardly to real expense of jquery. Many, many, many jquery-crutch sites are horrendously inefficient because they think that the magic of chaining and the robust selector language comes for free. It does not -- it comes at an often significant expense.


c'mon you know i meant that 10-20 lines are for an ie6+ solution.

You have to justify why you use something additive, not why not to use it.

If your decision not to use jQuery (or another lib that makes your life easier) is because of performance then you're optimising much too early.

Personally I optimise for developer time first and raw performance much further down the line.

And dom querying is not usually the bottleneck in most sloppy sites... its way too many event listeners. And jQuery comes to the rescue once again with extremely easy (to read and write) event delegation.

Sorry I don't mean to offend you or anything... but if you're rejecting jQuery or extjs or zepto etc. on the basis of performance then you're probably doing it wrong. Keystrokes count. Libraries allow you to focus less on plumbing. That's the whole point.


> If your decision not to use jQuery (or another lib that makes your life easier) is because of performance then you're optimising much too early.

LOL. That's the stupidest thing I ever heard. This is John Resig, isn't it? :)

> Personally I optimise for developer time first and raw performance much further down the line.

Yeah, you just set a new precedent. :(

> And dom querying is not usually the bottleneck in most sloppy sites...

You are allowed more than one bottleneck.

> its way too many event listeners. And jQuery comes to the rescue once again with extremely easy (to read and write) event delegation.

You just have no frame of reference.


> But if you absolutely have to support IE6, then yeah, use JQuery.

Absolutely NOT. The results vary per jQuery version as they have been struggling to grasp the subtle differences for six years.


> you're kidding me right? Obviously you filter your queries to the closest node.

Smart aleck doesn't suit you.

Obviously, you can use standard DOM methods (e.g. gEBTN, gEBCN) with the "closest node" as well.

And, assuming you mean an element node, you just bought yourself a world of hurt. jQuery and the like will use the Selectors API (e.g. QSA) when it suits them, and due to their disagreement with the specs, element nodes don't suit them. Some scripted query engines (e.g. YUI) ignore the disagreement, favoring wrong answers fast over right ones slower.

When the libraries use their own query code, performance and compatibility go right down the toilet.

In other words, use QSA with the document node, unless you want to relearn how queries work.

> Having css3 query support in legacy browsers is awesome.

Except that you don't have anything close to that (assuming you are using one of the "popular" libraries). And, even if you did, would you really want to send that crap to an iPhone?

Only way to do it efficiently is to load the library inside conditional comments and use QSA for everything else. That is assuming you can find a query engine that actually works as expected in IE 6/7.

>> massive speed losses from parsing > Nobody is searching the entire dom for matching nodes.

Parsing selectors is parsing selectors, regardless of how they will be used. One element or the entire DOM; it doesn't make a bit of difference.

> The single biggest performance killer... far more important than tree traversal is event overhead. As long as you think long and hard before applying a new event handler (and use delegation whenever possible) you'll be fine even with those 'Frankenstein' queries hehe :P

Again, event delegation is unrelated to queries. It's silly to assume you can use wasteful queries with impunity as long as you don't attach too many listeners.

Oh, but wait, jQuery tangles up queries and event delegation with its "Live" feature. So you are screwed either way. :(

And those "Frankenstein queries" are the exact opposite of self-documenting code (something most jQuery proponents/marketers get backwards).


> Having css3 query support in legacy browsers is awesome.

No it isn't as you send all of the supporting junk code to the newer browsers that don't need it.

> Not to mention productivity gains from method chaining and batch assignment such as $('.somehting').find('*').css({'font-weight': 'bold'});

Chaining has nothing to do with queries.

> Do you really want to type the 10-20 lines of JS that are required to make that happen? I don't.

Then learn to write (cross-browser) functions that fit your needs. Leave the ham-fisted queries alone.


Five years ago, this was definitely true; however, I've had pretty good luck lately writing code in Chrome that works equally well in Firefox or IE9 without any additional effort on my part. I'm a pure JS guy.

I used to do a lot of work in Flash, and one of the nicest parts was knowing that what you write works as intended across environments. One of the nice side-effects of the HTML5 mob is that the browser vendors are putting a lot of work into both improving their APIs and doing so in a cross-compatible way.


lucky you.. you don't have to support anything below ie9. Not everyone has that luxury.


There are a lot of them, trust me. Browsers have been improving? Wonderful, but some of us still need to support the unimproved ones. As grandparent says, dealing with these quirks is a waste of time and effort.

We've gotten to such a point of jQuery saturation that it seems some of us have forgotten why we use it in the first place. Which is really just the other side of the coin of people blindly using it without knowing why.


There are a lot of them, trust me.

I lead a team of developers building web apps day in and day out. I have a number of fairly cutting edge web samples in the wild. A "trust me" on an anonymous board is completely meaningless to me.

As grandparent says, dealing with these quirks is a waste of time and effort.

There are far less quirks than many imagine them to be. Further by providing some trivial syntactical sugar, jquery encourages a development style that is orthogonal with the DOM, incurring a significant performance penalty (horrid abuses like Twitter).

I'm not saying not to use jquery, and we do in several of our projects. But we justify why we use it, and never perversely demand a justification why not.


This post is moving towards the right direction, but not far enough I'm afraid.

Selectors are completely unnecessary. Class "selectors" are tar pits as they have to search every single node in the current context (usually the entire DOM) and then have to check for a class match amongst a possibility of multiple classes.

Quite simply, if you're using a class "selector", you're doing the user—and yourself—a great disservice. Use `id` hooks where possible and `HTMLCollection`s like `HTMLDocument::forms` and `HTMLFormElement::elements` when `id`s are unnecessary. The speed gains are huge.

Moreover, jQuery completely loses its appeal once the selectors are eschewed. The only legitimate options I see are the `classList` abstractions along with the animation methods. Both are easily replaced with far more modular options (I prefer David Mark's My Library).

In short, please learn about the DOM and how it operates. The browser "weirdness" tends to sort itself out once you realize what's going on.


Something I'm constantly trying to do is optimize client load times by removing things such at jQuery. It's very difficult for me to do as jQuery just improves my development speed tremendously but I'm getting there. I've started by "stripping out" jQuery and just using Sizzle.js which is the selector engine. Next step is removing Sizzle!


Isn't it just wasted effort though? If you're using hosted jQuery from Google or similar, it is likely it is already in the client cache... You may in fact find its faster to use jQuery than just Sizzle (which I imagine fewer have cached)


Speed is not just about page load. JQuery carries the weight of 1) Old browser support and 2) 6 years of backwards-compatibility requirement. Heavy JQuery use is the easiest way to guarantee your app will be sluggish to use.


Alternatively, this is something that the Application Cache would be ideal for. One-time download, cached forever. (Well, until they clear their cache.)


Isn't this a massive security risk? You're allowing 3rd party scripts to run in the comtext of your website.


It's not a bigger risk than people loading jquery from google, or including google maps or analytics or kissmetric or twitter or Facebook code.


JSONP is a clever hack to get around browser security so it can be risk, but you would generally use it only with trusted sites.


I've had similar thoughts recently. I'm fairly new to jQuery, so maybe I just still don't know how to use it properly, but sometimes I don't feel that the costs of adding another 'plug-in' and requiring another server call for another js file is worth it when my needs for the feature are low.

For instance, just recently I was looking into plug-ins for automatically changing text and color of input fields, but I only needed it once, and I ultimately decided it was much more efficient to just manually code this into the onclick:

> if(this.value==\'Search Products\'){ this.value=\'\';this.style.color=\'#000\';}


If you want to do this style of JS development and get backwards compatibility for 2005-era browsers (AJAX and event differences, basically) and no other "utilities" that just rename DOM functions and helpfully put them under 10 layers of property access indirection, Peter Michaux's Fork JavaScript is highly recommended (mirror: https://github.com/vsedach/fork-0.1.1). That's the way I like to write JavaScript.


It seems all dreamhost sites are currently down, including snook.ca. Here's the cached version -> http://webcache.googleusercontent.com/search?q=cache:http://...


I've recently thought about going 'Naked' JS, but I'm dubious about the benefits.

I haven't dug into the code, but doesn't jQuery already use native methods like querySelectorAll where available?

I guess if all you need is to query the document and you know your target audience is running a modern browser... then sure, save yourself 31k :)


> I haven't dug into the code, but doesn't jQuery already use native methods like querySelectorAll where available?

Yes. But it still has quite a bit of overhead as it also handles non-standard selectors (implemented in javascript), things like :input.

> I guess if all you need is to query the document and you know your target audience is running a modern browser... then sure, save yourself 31k :)

If you've got an ever more restricted target audience, you can also use things like Zepto (webkit-only, jQuery's interface in 7k)


That's why I like the idea (if not necessarily the implementation) of things like zepto.js. Keep the jQuery syntax. Use the tiny, optimised library when you can. Use jQuery when you can't.


Except you have no reliable to way to know when you can and when you can't (and no good way to swap between libraries). Best you can do is conditional comments to target old IE versions and you sure don't want jQuery on that team.


Yes, jQuery does utilize things like querySelectorAll (among other things) when available.


Not exactly correct. It uses QSA only under certain conditions. Unfortunately, the fallback code is not compatible with QSA (and not consistent across their "supported" browsers).


Love this. I don't like to include addons just to use a small subset of their functionality. On the other hand, I hate including cross browser hacks in my code. I think jQuery has a place, but is widely over used.


Maybe I'm being unnecessarily harsh here, but this seems to have about the same level of substance as a low-level JS tutorial you'd find on Nettuts or something.


The code may be something you could find on Nettuts but I think the point is to challenge the belief that we should all "just use jQuery". Not to show you how, but rather to explain why.

"How's" are easily Googleable, "why's" are a little harder and therefore more valuable, IMO.


If you are going to go that simple, then why even pass function formatCurrency on the main page, you can pass the whole function back with the document.body.appendChild method.

Then instead of 628 bytes, you'll have just 100 or so. Then make the script loader a re-usable function for other data on the page.


I agree entirely with this approach.

Especially when I consider that we're delivering a 350KiB minified Javascript hit on initial load just for jquery and a load of plugins.


Why are you loading 10x times the jQuery filesize in just plugins? Certainly you have a lot more bloat to trim before you should consider eliminating jQuery entirely.


It's a very complicated application with a huge amount of HTTP endpoints. We're talking over a million lines of code.


I mean if you use the CDN jQuery the likelihood of loading jQuery up is fairly low considering its so ambiguous.


Is this usually actually true? It makes a ton of obvious sense, but I've seen numbers thrown around that suggest a surprisingly low number of people actually end up taking advantage of the cache.


It's 100% not true. It's also a pain in the arse if you serve everything over SSL like we do.


To the best of my knowledge, the only reason SSL could cause a problem is if you are specifying the protocol (http:// vs https://). The best way to handle this is to use a protocol-relative URL like "//ajax.googleapis.com/mylibrary". The browser will then infer the correct protocol.


You've obviously never dealt with ancient IE versions and script loading then...


I'm happy to be enlightened if you feel like sharing.



Thank you for this.




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

Search: