Re: [SelectorsAPI] Selector detection needed?

[ccing the right list for this, and setting reply-to]
Nicholas C. Zakas wrote:

> The try-catch statement does carry overhead with it in terms of an additional
> scope. If you're doing a bunch of queries and you need to surround each of
> them with a try-catch, it can affect performance (see
> http://dev.opera.com/articles/view/efficient-javascript/?page=2).

What this is saying is that if you have to run the catch clause (that is, an 
exception was thrown) you get a small performance hit.  If you don't throw, no hit.

But in this case, that means that you're going to use a fallback querySelector 
implementation anyway, so you're getting a big performance hit no matter what. 
I'd be interested in how the overhead of the catch compares to that.  My gut 
instinct is that it's pretty insignificant.

It might be that the article isn't quite clear, so there is a hit even if 
nothing is thrown.  Again, hard data would be much appreciated.  Safari has a 
querySelector implementation that could be used to test this, for example. 
Alternately, I have a Gecko with such support here and would be happy to run a 
timing test if you come up with one.

> Errors should be thrown only for things that aren't easily detectable
> beforehand.

I'm not sure I agree.  There are plenty of DOM operations where it would be easy 
to add an API to check whether the operation is allowed before performing it... 
and they all throw if the operation is not allowed.

Given that querySelector would continue throwing on unsupported selectors 
whether the pre-check is added or not, how is this situation different?

> Not supporting a selector is not the same as a syntax error.

Sure it is, from the point of view of a UA.  A CSS parser + implementation 
really can't tell the two apart.

> Again, you're focusing in on the specific solution.

No.  I'm asking for two things:

1)  Concrete use cases.  I have yet to see a decent one suggested.
2)  Proposed solutions to solve those use cases.

These are somewhat orthogonal.  (1) is more important.

> The DOM has tons of different ways to determine what is
> implemented and possible to use.

Most of them highly unreliable.  And as I said before, it also has plenty of 
cases where such things are not available and operations either succeed or throw 
and let the caller deal.

> An unsupported selector doesn't necessarily break CSS syntax. Consider that
> :after and :hover match the same pattern.

The "CSS syntax" (as opposed to the grammar) is something that doesn't exist. 
There is a "CSS2.1 syntax", which is the set of all things allowed in CSS 2.1. 
There is the "Selectors syntax" which is the set of all things allowed in the 
Selectors CSS3 module.  But a parser that only supports part of the module 
doesn't have any idea whether the other things are "syntax errors" or just CSS 
it happens to not support.  Nor is introducing such a dichotomy really desirable.

An example.  Is "a::before:hover" a syntax error?  Or an unsupported selector? 
How do you know?

> A support status page could be useful, but I'm thinking more practical.

Yes, practical is good.

> How can a JavaScript library that currently supports CSS querying determine if it
> should use its implementation or the browser one?

I'd be interested in some feedback from actual JavaScript library authors on 
what they would find useful here, for what it's worth.

> Again, writing a try-catch around every call adds performance overhead

As I said, I'd love data here, especially as compared to proposals to query 
selector support.  For example, is it more overhead than parsing the selector 
twice on every call (once to test support, once to run the query)?

> With some way to detect
> the capabilities of the query engine, a JS library could determine up front
> whether or not to use the browser-native version.

If it's only doing the detection once up front, it doesn't really matter whether 
the detection is expensive...

> var goodEnough = document.querySelectorSupport(":hover", ":not", ".a.b",
> "tagname", "#id");
> 
> In this paradigm, you can pass in a string representing each selector to
> test, with special ones for single class names (.a), multiple (.a.b, .a.b.c,
> etc.), tag names (tagname), IDs (#id).

Maybe I'm missing something... how would this work in practice?  Wouldn't this 
require the JS library to parse every selector it needs to query to see whether 
it's in its precomputed "safe" set?  My gut feeling is that this is more 
overhead than a try/catch.  Of course actual data would be welcome.

I should note that your ":not" example above seems to fail my ":not(.a.b)" test, 
by the way.

-Boris

Received on Thursday, 10 April 2008 05:11:24 UTC