DescriptionSchedule sibling invalidation sets for sibling insert/remove.
Invalidation sets have been used only for changes which do not alter the
tree structure, like changing id, class names, other attributes, and
pseudo states. For dom tree changes, style invalidation relies on attach
and detach of the layout tree for the inserted/removed element. For
subsequent siblings of inserted/removed elements, we have been marking
siblings for subtree recalc (when we know we have tried to match
adjacent combinators on one of the siblings before) based on the maximum
number of consecutive direct adjacent combinators or all subsequent
siblings for indirect adjacent combinators.
This CL starts using sibling invalidation sets on siblings instead of
doing subtree recalcs.
The following properties of invalidation sets affected how this
implementation was done:
* Even though we invalidate descendants/siblings based on tag names, we
don't have invalidation sets for tag names as elements do not change
tag names dynamically. For inserted/removed elements, we could have
used invalidation sets for tag names. Take the selector "div + span".
If we remove a div we could have scheduled an invalidation set for div
which invalidates a span sibling.
* Invalidation sets for simple selectors and their negated versions, for
instance ".a" and ":not(.a)", share invalidation sets and they may do
so because invalidation sets have been applied when they change. That
is, "a" is either part of old or the new class attribute when the
invalidation set needs to be scheduled. When removing/inserting
elements, a selector like ":not(.a) + .b" will need to schedule a
sibling for ".a" for all elements not having the class "a".
* Consider the selector "* + .a". We have to schedule a sibling
invalidation for any inserted/removed element to invalidate a sibling
with class "a". However, invalidation set construction has only
created an invalidation set for ".a" with the invalidateSelf flag set.
For this CL, we create a single universal sibling invalidation set to
handle the cases above. In fact this CL only do sibling invalidations on
element insert/remove for id, class, and attribute in addition to
scheduling the universal sibling invalidation set. Also, we skip
selector lists (that is, :not() and :-webkit-any() as :host()
:host-context() and :slotted() never match when followed by an adjacent
combinator).
For the following set of selectors:
:not(.a) + .b + .c
#x:not(.a) + .d
div + span
:-webkit-any(.x) + .f .g
We end up with the following universal sibling invalidation set with the
descendant invalidation set, containing ".g", to the right.
{ .c, span, .f, invalidatesSelf } => { .g }
Note that if a compound contains both :not() and for instance an id
selector, we will not add it to the universal sibling invalidation set
as we can properly invalidate ".d" siblings above using the invalidation
set for "#x".
== Scheduling sibling invalidations
For changes not modifying the tree, we schedule sibling invalidation
sets on the changed element and invalidate the siblings with descendant
sets during the invalidation process. When removing an element, however,
the element is not left in the tree, so we need to associate the
invalidation set with another element.
When we remove an element, we instead schedule the sibling invalidation
set, and the sibling invalidation set's descendant set, as descendant
invalidation sets on the parent element or shadow root.
Likewise for inserting an element. When inserting an element, we have
elements to schedule the sibling sets on, but the sets would need to be
scheduled on elements further to the right in the sibling list in order
to reach the siblings we needed to invalidate. Also, they would have to
be moved further right on subsequent insertions.
== The effect on amazon.com
This CL gets rid of all post-page-load full recalcs before you start
interacting with the page. The full recalcs after you start interacting
needs to be investigated further.
R=esprehn@chromium.org,ericwilligers@chromium.org
BUG=542082
Committed: https://crrev.com/1f82047b13f02be39b8104b6afda0615e60a7cee
Cr-Commit-Position: refs/heads/master@{#402770}
Patch Set 1 #Patch Set 2 : Rebased #Patch Set 3 : Corrected DCHECK #
Total comments: 12
Patch Set 4 : Removed minDirectAdjacent optimization. #Messages
Total messages: 28 (9 generated)
|