Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: da79705ade01755efb0bf2144b1636e4e744a592
      
https://github.com/WebKit/WebKit/commit/da79705ade01755efb0bf2144b1636e4e744a592
  Author: Ahmad Saleem <[email protected]>
  Date:   2026-09-04 (Fri, 04 Sep 2026)

  Changed paths:
    M Source/WTF/wtf/Vector.h
    M Source/WebCore/page/scrolling/ScrollingStateTree.cpp
    M Tools/TestWebKitAPI/Tests/WTF/Vector.cpp

  Log Message:
  -----------
  ScrollingStateTree::insertNode does redundant work reordering children on 
pages with many sibling scrolling nodes
https://bugs.webkit.org/show_bug.cgi?id=322891
rdar://186143008

Reviewed by Chris Dumez and Simon Fraser.

ScrollingStateNode keeps its children in a Vector. When insertNode() moves an
existing node to a new index it called removeChild() (a linear scan plus a tail
memmove) followed by insertChild()/appendChild() (another tail memmove). Since
registerScrollingNodeID() runs this once per layer during every compositing
update, a parent with N children that need reordering does more shifting than
necessary.

Add Vector::moveTo(), which relocates the element at one index to another by
lifting it out, shifting only the elements between the current and target
positions into the gap with Vector's own TypeOperations::moveOverlapping(), and
dropping it back at its new home. Every element outside that range stays put.
ScrollingStateTree::insertNode() now finds the node once and calls moveTo()
instead of remove + insert.

This is a constant-factor improvement, not an asymptotic one: the find() is
still O(n) and moveTo() shifts O(distance) elements, so a full reordering of N
siblings remains O(n^2) in the worst case. What it removes is the redundant
work each reorder did before -- one bounded shift instead of a full-length
remove memmove plus a full-length insert memmove -- and, in the common case
where a node moves only a short distance, the shift touches just the elements
in between rather than the whole tail.

The reorder path is unchanged behaviorally, so it stays covered by existing
tests. A childIndex of notFound (or otherwise past the end) still means
"append": it is clamped to the last slot, preserving the tolerance
insertChild() has long needed for the out-of-range indices that crash data
shows do occur, rather than tripping moveTo()'s bounds assertion. moveTo()
itself gets direct coverage in TestWebKitAPI, including same-position and
move-only element cases.

* Source/WTF/wtf/Vector.h:
(WTF::Vector::moveTo):
* Source/WebCore/page/scrolling/ScrollingStateTree.cpp:
(WebCore::ScrollingStateTree::insertNode):
* Tools/TestWebKitAPI/Tests/WTF/Vector.cpp:
(TestWebKitAPI::TEST):

Canonical link: https://commits.webkit.org/320527@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to