Skip to content

Conversation

@mgol
Copy link
Member

@mgol mgol commented Aug 9, 2019

Summary

The :scope pseudo-class has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then :scope stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

Fixes gh-4453
Ref gh-4332
Ref jquery/sizzle#405

Checklist

@mgol
Copy link
Member Author

mgol commented Aug 9, 2019

Currently, the PR adds 49 bytes gzipped. I'd welcome suggestions how to compress it but I'd argue even at this size increase it's worth it due to the fact it removes layout thrashing from the place people don't expect it may be, i.e. regular DOM querying.

@mgol mgol requested review from gibson042 and timmywil August 9, 2019 10:45
@mgol
Copy link
Member Author

mgol commented Aug 9, 2019

We'll be able to reduce the space impact from +49 to +22 bytes once we drop support for EdgeHTML and we can remove the support test in favor of an isIE check.

@mgol
Copy link
Member Author

mgol commented Aug 9, 2019

Reduced to +43 bytes.

EDIT: If we could drop EdgeHTML & rely on the isIE check, it'd be +17 bytes.

The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then `:scope` stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

Fixes jquerygh-4453
Ref jquerygh-4332
Ref jquery/sizzle#405
@mgol
Copy link
Member Author

mgol commented Aug 12, 2019

Reduced to +37 bytes (see the newest commit).

@mgol
Copy link
Member Author

mgol commented Aug 16, 2019

I added a test to ensure Mutation Observers are not fired for non-sibling selections.

@mgol mgol merged commit df6a7f7 into jquery:master Aug 19, 2019
@mgol mgol deleted the perf-css-scope branch August 19, 2019 16:41
mgol added a commit to mgol/sizzle that referenced this pull request Aug 19, 2019
The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then `:scope` stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

Fixes jquery/jquery#4453
Ref jquery/jquery#4454
Ref jquery/jquery#4332
Ref jquerygh-405
mgol added a commit to mgol/sizzle that referenced this pull request Aug 20, 2019
The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then `:scope` stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

Fixes jquery/jquery#4453
Ref jquery/jquery#4454
Ref jquery/jquery#4332
Ref jquerygh-405
mgol added a commit to mgol/sizzle that referenced this pull request Aug 20, 2019
The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then `:scope` stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

Fixes jquery/jquery#4453
Ref jquery/jquery#4454
Ref jquery/jquery#4332
Ref jquerygh-405
mgol added a commit to mgol/sizzle that referenced this pull request Aug 21, 2019
The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then `:scope` stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

Fixes jquery/jquery#4453
Ref jquery/jquery#4454
Ref jquery/jquery#4332
Ref jquerygh-405
mgol added a commit to mgol/sizzle that referenced this pull request Aug 21, 2019
The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then `:scope` stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

Fixes jquery/jquery#4453
Ref jquery/jquery#4454
Ref jquery/jquery#4332
Ref jquerygh-405
mgol added a commit to mgol/sizzle that referenced this pull request Aug 21, 2019
The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then `:scope` stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

Fixes jquery/jquery#4453
Ref jquery/jquery#4454
Ref jquery/jquery#4332
Ref jquerygh-405
mgol added a commit to mgol/sizzle that referenced this pull request Aug 21, 2019
The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then `:scope` stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

Fixes jquery/jquery#4453
Ref jquery/jquery#4454
Ref jquery/jquery#4332
Ref jquerygh-405
mgol added a commit to mgol/sizzle that referenced this pull request Oct 1, 2019
The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then `:scope` stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

Fixes jquery/jquery#4453
Ref jquery/jquery#4454
Ref jquery/jquery#4332
Ref jquerygh-405
mgol added a commit to jquery/sizzle that referenced this pull request Oct 10, 2019
The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome,
Firefox & Safari have supported if for a long time; only IE & Edge lack support.
This commit leverages this pseudo-class to get rid of the ID hack in most cases.
Adding a temporary ID may cause layout thrashing which was reported a few times
in [the past.

We can't completely eliminate the ID hack in modern browses as sibling selectors
require us to change context to the parent and then `:scope` stops applying to
what we'd like. But it'd still improve performance in the vast majority of
cases.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

Fixes jquery/jquery#4453
Closes gh-453
Ref jquery/jquery#4454
Ref jquery/jquery#4332
Ref gh-405
mgol added a commit to mgol/sizzle that referenced this pull request Oct 11, 2019
An optimization added in jquery#431 skips the temporary IDs for selectors
not using child or descendant combinators. There are a few issues with this
optimization, though:
1. For sibling combinators, this pushes a selector with a leading combinator to
   qSA directly which crashes and falls back to a slower Sizzle route.
2. qSA in IE/Edge doesn't find elements with an empty name attribute selector
   (`[name=""]`) but it does find them when there's an ID prefix for the
   selector (`#test [name=""]`). Therefore, skipping the ID prefix more hurts
   than helps.
3. After jquery/jquery#4454 & jquery#453, all modern browsers other than
   Edge don't get temporary IDs assigned as we leverage the :scope pseudo-class.
   Therefore, the optimization doesn't buy us as much.
4. The regex testing the child/descendant combinators checks for `+` and
   whitespace as whitespace is how a descendant selector is constructed.
   However, users often insert spaces to selectors for readability reasons, not
   knowing it would cause a performance penalty.
mgol added a commit to mgol/sizzle that referenced this pull request Oct 12, 2019
An optimization added in jquery#431 skips the temporary IDs for selectors
not using child or descendant combinators. There are a few issues with this
optimization, though:
1. For sibling combinators, this pushes a selector with a leading combinator to
   qSA directly which crashes and falls back to a slower Sizzle route.
2. qSA in IE/Edge doesn't find elements with an empty name attribute selector
   (`[name=""]`) but it does find them when there's an ID prefix for the
   selector (`#test [name=""]`). Therefore, skipping the ID prefix more hurts
   than helps.
3. After jquery/jquery#4454 & jquery#453, all modern browsers other than
   Edge don't get temporary IDs assigned as we leverage the :scope pseudo-class.
   Therefore, the optimization doesn't buy us as much.
4. The regex testing the child/descendant combinators checks for `+` and
   whitespace as whitespace is how a descendant selector is constructed.
   However, users often insert spaces to selectors for readability reasons, not
   knowing it would cause a performance penalty.
mgol added a commit to mgol/sizzle that referenced this pull request Oct 13, 2019
An optimization added in jquery#431 skips the temporary IDs for selectors
not using child or descendant combinators. For sibling combinators, though, this
pushes a selector with a leading combinator to qSA directly which crashes and
falls back to a slower Sizzle route.

This commit makes selectors with leading combinators not skip the selector
rewriting. Note that after jquery/jquery#4454 & jquery#453, all modern
browsers other than Edge leverage the :scope pseudo-class, avoiding temporary
id attributes
mgol added a commit to mgol/sizzle that referenced this pull request Oct 13, 2019
An optimization added in jquery#431 skips the temporary IDs for selectors
not using child or descendant combinators. For sibling combinators, though, this
pushes a selector with a leading combinator to qSA directly which crashes and
falls back to a slower Sizzle route.

This commit makes selectors with leading combinators not skip the selector
rewriting. Note that after jquery/jquery#4454 & jquery#453, all modern
browsers other than Edge leverage the :scope pseudo-class, avoiding temporary
id attributes
mgol added a commit to mgol/jquery that referenced this pull request Oct 13, 2019
An optimization added in jquery/sizzle#431 skips the temporary IDs for selectors
not using child or descendant combinators. For sibling combinators, though, this
pushes a selector with a leading combinator to qSA directly which crashes and
falls back to a slower Sizzle route.

This commit makes selectors with leading combinators not skip the selector
rewriting. Note that after jquery#4454 & jquery/sizzle#453, all modern
browsers other than Edge leverage the :scope pseudo-class, avoiding temporary
id attributes
mgol added a commit to mgol/jquery that referenced this pull request Oct 13, 2019
An optimization added in jquery/sizzle#431 skips the temporary IDs for selectors
not using child or descendant combinators. For sibling combinators, though, this
pushes a selector with a leading combinator to qSA directly which crashes and
falls back to a slower Sizzle route.

This commit makes selectors with leading combinators not skip the selector
rewriting. Note that after jquery#4454 & jquery/sizzle#453, all modern
browsers other than Edge leverage the :scope pseudo-class, avoiding temporary
id attributes

Ref jquery/sizzle#431
mgol added a commit to mgol/sizzle that referenced this pull request Oct 13, 2019
An optimization added in jquery#431 skips the temporary IDs for selectors
not using child or descendant combinators. For sibling combinators, though, this
pushes a selector with a leading combinator to qSA directly which crashes and
falls back to a slower Sizzle route.

This commit makes selectors with leading combinators not skip the selector
rewriting. Note that after jquery/jquery#4454 & jquery#453, all modern
browsers other than Edge leverage the :scope pseudo-class, avoiding temporary
id attributes

Ref jquerygh-431
mgol added a commit to mgol/sizzle that referenced this pull request Oct 13, 2019
An optimization added in jquery#431 skips the temporary IDs for selectors
not using child or descendant combinators. For sibling combinators, though, this
pushes a selector with a leading combinator to qSA directly which crashes and
falls back to a slower Sizzle route.

This commit makes selectors with leading combinators not skip the selector
rewriting. Note that after jquery/jquery#4454 & jquery#453, all modern
browsers other than Edge leverage the :scope pseudo-class, avoiding temporary
id attributes.

Ref jquerygh-431
mgol added a commit to mgol/jquery that referenced this pull request Oct 13, 2019
An optimization added in jquery/sizzle#431 skips the temporary IDs for selectors
not using child or descendant combinators. For sibling combinators, though, this
pushes a selector with a leading combinator to qSA directly which crashes and
falls back to a slower Sizzle route.

This commit makes selectors with leading combinators not skip the selector
rewriting. Note that after jquery#4454 & jquery/sizzle#453, all modern
browsers other than Edge leverage the :scope pseudo-class, avoiding temporary
id attributes.

Ref jquery/sizzle#431
mgol added a commit to jquery/sizzle that referenced this pull request Oct 14, 2019
An optimization added in #431 skips the temporary IDs for selectors
not using child or descendant combinators. For sibling combinators, though, this
pushes a selector with a leading combinator to qSA directly which crashes and
falls back to a slower Sizzle route.

This commit makes selectors with leading combinators not skip the selector
rewriting. Note that after jquery/jquery#4454 & #453, all modern
browsers other than Edge leverage the :scope pseudo-class, avoiding temporary
id attributes.

Closes gh-460
Ref gh-431
mgol added a commit that referenced this pull request Oct 14, 2019
An optimization added in jquery/sizzle#431 skips the temporary IDs for selectors
not using child or descendant combinators. For sibling combinators, though, this
pushes a selector with a leading combinator to qSA directly which crashes and
falls back to a slower Sizzle route.

This commit makes selectors with leading combinators not skip the selector
rewriting. Note that after #4454 & jquery/sizzle#453, all modern
browsers other than Edge leverage the :scope pseudo-class, avoiding temporary
id attributes.

Closes gh-4509
Ref jquery/sizzle#431
@lock lock bot locked as resolved and limited conversation to collaborators Feb 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Development

Successfully merging this pull request may close these issues.

Leverage the :scope pseudo-class instead of the ID hack where possible

2 participants