Servo/StyleUpdateOnDOMChange: Difference between revisions

Line 33: Line 33:


This setup, again, makes sure that dynamic changes are not missed, while trying to optimize the common append case as much as possible.  But it will often be more pessimistic than it needs to be, and in particular can end up flagging with slow selector flags elements whose descendants don't actually match the selector with the structural pseudo-class or sibling combinator anyway, because of a simple selector further to the left which fails to match ancestors of the flagged element.
This setup, again, makes sure that dynamic changes are not missed, while trying to optimize the common append case as much as possible.  But it will often be more pessimistic than it needs to be, and in particular can end up flagging with slow selector flags elements whose descendants don't actually match the selector with the structural pseudo-class or sibling combinator anyway, because of a simple selector further to the left which fails to match ancestors of the flagged element.
== WebKit's handling of style updates ==
=== Attribute changes ===
If the element does not already have a style recalc flagged, and if either the attribute is the id attribute or there are selectors that involve the attribute, the element is flagged for a style recalc.  There is no attempt to double-check whether those selectors have anything to do with the element and no attempt to handle cases involving '~' and '+' at this stage.  There is also a separate hook called when class attributes change that amongst other things unconditionally flags the element as needing a style recalc.  Again, no attempt is made to handle '~' and '+'.  In none of these cases is there an attempt to optimize away selector matching on descendants.
=== State changes ===
There is no unified setup for state changes in WebKit.  For each pseudo-class that is handled via boolean states in Gecko, selector matching has a dedicated function the element that it can call to test whether that pseudo-class matches.  Changes to that state inside an element are responsible for directly marking that element as needing style recalc.  Again, no attempt to optimize away selector matching on descendants or to handle '+' or '~' is made.  There are some optimizations here similar to the one Gecko makes for :hover that cover :hover, :active, and something about dragging.
=== Handling of insertions and deletions ===
The RenderStyle has flags that indicate whether its kids are affected by various structural pseudo-classes and '+' or '~' combinators.  On DOM mutations, the first affected element after the change (in child list order) is marked as needing a style recalc, or the single first child of the parent if it might need a recalc.  If more things before the change might need a recalc, then the parent is marked as needing a style recalc, which will recalc all its kids.
In all of these cases, when actually recomputing style on an element, a check is made to see whether its kids are affected by '+' or '~'.  If so, then if any child is flagged as needing style recalc either the child after it or all children after it (depending on whether '+' or '~' was involved) are also flagged as needing style recalc.
The upshot is that in some cases WebKit ends up recomputing style on a lot more elements than Gecko does, as far as I can tell, but in others it ends up recomputing style on many fewer elements.  XXXbz At least the latter is the only way I can explain its behavior on the HTML5 spec.  What I don't undertstand is why it ends up with that behavior, since it flags the "children affected by" flags just as eagerly as Gecko does...  Anyone know offhand?
The other upshot is that the work involved in individual attribute and state changes is much less than in Gecko, at the cost of more style recomputation.  The work involved in DOM insertion/deletion is about the same.
== Options for Servo ==
308

edits