Commit graph

3 commits

Author SHA1 Message Date
Andreas Kling
bae4434780 LibWeb: Avoid sibling walks for last-child invalidation
Track last-child and backward positional selector dependencies
separately on parent nodes. A last-child or only-child selector can only
change the element at the trailing edge, so insertions and removals can
invalidate that element directly instead of walking every previous
sibling.

Keep the previous-sibling walk for selectors such as nth-last-child and
last-of-type, where every previous element's from-end position may
change.
2026-06-08 17:16:18 +02:00
Andreas Kling
de7ed9a498 LibWeb: Target :first/:last/:only-child sibling invalidation precisely
invalidate_structurally_affected_siblings used to mark every previous
or next sibling that had ever observed :first-child, :last-child, or
:only-child. Their match result can flip for at most one element per
single mutation, so compute that transition target once and only mark
it. The :nth-child and :nth-last-child paths still re-evaluate every
affected sibling since their indices shift on every mutation.

Drops elementStyleNoopRecomputations from ~22000 to ~15000 on the
github.com/LadybirdBrowser/ladybird page (60s settle, three-run
median). Rebaselines the structural-pseudo-class-precision test, with
the :nth-child / :nth-last-child counters intentionally unchanged.
2026-05-06 21:22:02 +02:00
Andreas Kling
95eb41092c LibWeb: Move structural mutation invalidation into a helper
Node.cpp still contained selector-specific policy for sibling and
same-parent-move structural invalidation. Move that logic into
CSS::Invalidation::StructuralMutationInvalidator so DOM mutation code
can delegate structural selector dependency handling.

This is a behavior-preserving extraction. It keeps the existing
previous-sibling walk guard, sibling-distance checks, shadow-root
marking, and ancestor child-needs-style propagation.
2026-04-29 15:47:23 +02:00