9

In a piece of example code I wrote

var as = toArray(document.getElementsByClassName("false")).filter(function (el) {
    return el.tagName === "A";
});

And I was thinking I could replace that with

var as = document.querySelectorAll("a.false");

Now after reading the following facts

  • Pretend browser support isn't an issue (we have shims and polyfills).
  • Pretend your not in your generic jQuery mindset of you shall use QSA for getting every element.
  • I'm going to write qsa instead of document.querySelectorAll because I'm lazy.

Question: When should I favour QSA over the normal methods?

It's clear that if your doing qsa("a") or qsa(".class") or qsa("#id") your doing it wrong because there are methods (byTagName, byClassName, byId) that are better.

It's also clear that qsa("div > p.magic") is a sensible use-case.

Question: But is qsa("tagName.class") a good use-case of QSA?

As a futher aside there are also these things called NodeIterator

I've asked a question about QSA vs NodeIterator

Community
  • 1
  • 1
Raynos
  • 166,823
  • 56
  • 351
  • 396
  • As an aside [NodeIterator is really slow](http://jsperf.com/qsa-vs-node-iterator) – Raynos Oct 29 '11 at 19:49
  • 1
    Well, I'd say that until `getElementsByTagNameAndClassName()` becomes available, `querySelectorAll("a.false")` makes sense and is more readable than a chained call from `toArray()` to `filter()`. – Frédéric Hamidi Oct 29 '11 at 20:07
  • @FrédéricHamidi an additional call to `.filter` is also slow as hell. – Raynos Oct 29 '11 at 20:11
  • Indeed, and, until an hypothetical `getElementsByTagNameAndClassName()` manifests itself, you don't have much choice outside of `querySelectorAll()`, do you? – Frédéric Hamidi Oct 29 '11 at 20:12

3 Answers3

2

You should use QSA when the gEBI, gEBN, gEBCN do not work because your selector is complex.

QSA vs DOM parsing is a matter of preference and what your going to be doing with the returned data set.

Raynos
  • 166,823
  • 56
  • 351
  • 396
1

If browser support was not an issue I would just use it everywhere. Why use 4 different methods (...byId, ...byTagName, ...byClassName) if you could just use one.

QSA seems to be slower (...byId), but still only takes a few miliseconds or less. Most of the times you only call it a few times, so not a problem. When you hit a speed bottleneck you could always replace QSA with the appropriate other one.

Gerben
  • 16,747
  • 6
  • 37
  • 56
  • By slower you mean about TWO HUNDRED times slower. I already know for simple selectors QSA is stupid (as mentioned) – Raynos Oct 29 '11 at 20:51
  • 1
    @Raynos you should not just look at the speeds relative to each other. You should look at how many milliseconds a call takes. So where getElementById takes 0.0001ms in FX7, QSA takes 0.02ms. Unless you need to select thousands of elements the end user will not notice any difference. – Gerben Oct 30 '11 at 12:32
  • woh! milliseconds count! 0.02ms is slow. That's a whole 20micro seconds. At most I want to do 100 micro seconds of computation. – Raynos Oct 30 '11 at 12:50
  • why 100 micro seconds. Humans can only detect 200ms at best. So you can do a lot of JS and still allow the engine to redraw the page in 200ms. – Gerben Oct 30 '11 at 13:53
  • 1
    It depends entirely on what you're doing. If all you need to do is attach some basic logic to an otherwise static page, a couple calls to QSA is completely fine and will save you development time. If you're working with thousands of DOM elements and some complex logic, you have to be looking at performance. I wouldn't say doing one or the other is "stupid", it just depends on what you need. – Sasha Chedygov Jan 07 '13 at 19:06
0

I've set up some tests for you to mess around with. It appears that QSA is a lot slower. But if you are not calling it that much, it shouldn't be a problem.

http://jsfiddle.net/mxZq3/

EDIT - jsperf version

http://jsperf.com/qsa-vs-regular-js

Will
  • 19,661
  • 7
  • 47
  • 48