Re: element existence selector

On Sat, Feb 28, 2015 at 10:36 PM, Peter Krauss <ppkrauss@gmail.com> wrote:
>
> Hello,
> First a general and summarized reply:
>
> Only now I understand better what Tab Atkins said, sorry (!),
> about "fast profile"... It is in fact a standard for CSS,
>
>    http://www.w3.org/TR/selectors4/#fast-profile   (2013)
>    http://dev.w3.org/csswg/selectors-4/#profiles   (2015)
>
> so, we can put the discussion in this more objective terms:
>
> 1* the pseudo-selector ":has()"  not is a good candidate to fast-profile...  (All agree with the W3C csswg 2015's draft??)
>
> 2* the suggestion of an ":hasID()" can be a good alternative to the fast-profile??
>
> NOTE:  fast-profile is a standard, so, we MUST agree that the standard defines a line separating fast from slow,
> it is not a personal taste matter... We can imagine a standard threshold in a standard benchmark-kit .
>

You can actually think of it more accurately in terms of computational
complexity, not speed - something that isn't as computationally
complex is also generally fast.  The problem is really that browsers
do amazing things in terms of applying CSS rule to winnow down the
number of rules by looking at what kinds of rules can possibly affect
the painting of something that mutates within the DOM - during the
initial parse, everything is mutating, so this is especially important
because of the expectation that things are rendered while still
downloading.  With very few exceptions CSS specifically hasn't allowed
the sorts of constructs which could allow you to write things we can't
figure out ways to optimize - or would have to be in some
Schrödinger's cat style state until the full document is loaded.  Keep
in mind here, I'm not saying that I support this stance above all
else, it's just the one that is relevant and that you're questioning.

>
> - - - - -
> My position about item 1:
>   I agree  that is not fast.
>   Selector ":has()" is good for PrinceXML, but is not good for web-browsing in a tablet.

"Good" is sounds like a matter of personal taste - I'm not sure how
you objectively base this. XPath and XSL did allow you to express some
of those sorts of things - is that good or bad?  What you can say is
creating a system in which you have to know about the whole document
before you can convincing say something like 'the background of the
page should be blue' is bad for the ability to progressively render
pages which include rules like that.  That I think you can safely say.

> My position about item 2:
>    I understand that "e1:hasID(#id1) #id2" is faster than "e1:has(any1) any2"
>    I understand that the only-ID  reduce the risk of complexity in a worst-case-set of selectors,
>    and CSS-parsing implementations based in  getElementById()  is faster than any others.
>    So, an ":hasID()" pseudo-selector can be use without performance reduction in a tablet.

See my comments below...

> - - - -
>    As Henrik suggested when replying Tab, perhaps we need to "elaborate on why it is slow"
>    with worst-case examples and some benchmarking (ex. by jQuery).
>    Some explanation about "why is slow" is here,
>         http://stackoverflow.com/q/1817792/287948
>     "(...) The document can be traversed once, matching elements as you go,
>         with no need to ever go backward to adjust a match
>     "
>
> - - - -
> Thanks Daniel for correct syntax, yes,
>     html:has(#id1:hover) #id2
>
> - - - -
> Brian,
>
> I not agree that "(...) there's not really a functional difference (...)"
> the little difference is what decides if a selector goes to the fast-profile or not,
> and getElementById() is the faster (!).
>

I think you're confusing the way a DOM method works and the term "fast
profile" in here, so let me explain a little.  The DOM method
getElementById is fast, but it has almost nothing to do with how CSS
works or what an ID means to CSS.  If you imagine a tree with 100k
elements and the 100,000th element is the one with that ID on it, then
you'd effectively have to search the entire tree to find it, but in
*most* cases you can short-circuit and bail much earlier.  Further,
since this method, as you rightly notice always points to a single
element, and because this method belongs in JS (DOM) which will be
evaluated at a fixed point in time, just once, you could at least in
theory have already mapped the 'getElementById' answer such that it is
a simple lookup.  But that is just that method and it doesn't
necessarily mean what you think it means.  The DOM itself actually
supports many elements with the same ID and so does CSS - it's always
been this way, but specs didn't always reflect it - you can see now it
is specified (http://w3c.github.io/dom/#dom-nonelementparentnode-getelementbyid)
that in the event that there is more than one, the DOM will return the
first one.  You can try this out in CSS.  Likewise, people expect qsa
to match and so if you do querySelectorAll, you'll get all of them and
if you do querySelector you'll find the first in document order.  CSS
really has no concept of the 'first in document order' style of id
selector, underneath, the optimizations done for id, class and
attribute are all effectively the same and they deal with clever ways
of winnowing down possible rules and the size of the subtree that they
have to be evaluated on whenever a change happens based on pure logic
that can be drawn from the strictness of these rules.  Thus, as I say,
it makes no functional difference.


> krauss
>
>
>
> 2015-02-27 18:16 GMT-03:00 Brian Kardell <bkardell@gmail.com>:
>>
>>
>>
>> On Fri, Feb 27, 2015 at 4:04 PM, Daniel Tan <lists@novalistic.com> wrote:
>>>
>>> On 2/28/2015 1:30 AM, Peter Krauss wrote:
>>>>
>>>> Thanks Tab, now you find exacly what I was looking for (!)...
>>>> Well, let's confirm it, with another words,
>>>>   1* you are  referring to the  "4.4. The Relational Pseudo-class
>>>> /:has()/ <http://dev.w3.org/csswg/selectors-4/#relational>";
>>>>   2* what I need is to use /:has()/ as a root's condition, like
>>>> /html:has(#id1)/;
>>>>   3* the samantic of "/a:has(b) c/" is "if /b/ then selects /c/";
>>>>   4* the semantic of "/html:has(#id1):hover #id2/" is "when
>>>> on-mouse-over /#id1/, selects /#id2/";
>>>>
>>>
>>> Syntactically, the correct way of writing such a selector would be
>>>
>>> html:has(#id1:hover) #id2
>>> /* or :root:has(... */
>>>
>>>> is it? assuming we agree until here, about this 4 assertions...
>>>> And perhaps I understand  when you say "(...) too slow, and makes
>>>> invalidating styles too difficult",
>>>> but now imagine a more specific selector, a /:has()/ that can be used
>>>> only with IDs,
>>>>
>>>> */:hasID()/ *
>>>>
>>>> so, why  "/html:hasID(#id1):hover #id2/"  will be slow? What the
>>>> validation problem?
>>>>
>>>> Perhaps this ID constraints "put in rails" my suggestion:
>>>> you see some parsing or validation problem with this hypothetical
>>>> /:hasID()/?
>>>>
>>>>
>>>
>>> Based on the explanation Boris has now given, I don't see how this will be any better than :has() except that it's restricted to an ID, which by itself has very little performance impact if at all.
>>>
>>> What I can tell, as an author, is that this basically forces you to use IDs, so you will only be able to use it with unique elements in a conforming document. If you only have one (or two) elements that you'll be using this with, I guess it's fine, but if you have several related elements that you would normally otherwise select with a class, things will get very unwieldy from there.
>>>
>>>
>>> --
>>> Daniel Tan
>>> NOVALISTIC
>>> <http://NOVALISTIC.com>
>>>
>>
>> Actually, there's not really a functional difference between a class and an ID other than some minor internal details and the fact that getElementById will automatically get you the first one in document order, so an ID really wouldn't make much difference here on either the author or performance end.
>>
>> --
>> Brian Kardell :: @briankardell :: hitchjs.com
>
>



-- 
Brian Kardell :: @briankardell :: hitchjs.com

Received on Sunday, 1 March 2015 19:03:42 UTC