Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 8dea23390c0a696e653060945077c219aefe84d0
https://github.com/WebKit/WebKit/commit/8dea23390c0a696e653060945077c219aefe84d0
Author: Brent Fulgham <[email protected]>
Date: 2026-09-24 (Thu, 24 Sep 2026)
Changed paths:
A LayoutTests/fast/forms/fieldset/fieldset-grid-legend-hit-test-expected.txt
A LayoutTests/fast/forms/fieldset/fieldset-grid-legend-hit-test.html
A PerformanceTests/Layout/grid-items-with-distinct-order.html
M
Source/WebCore/SaferCPPExpectations/NoUncheckedPtrMemberCheckerExpectations
M Source/WebCore/inspector/InspectorOverlay.cpp
M Source/WebCore/rendering/Grid.cpp
M Source/WebCore/rendering/Grid.h
M Source/WebCore/rendering/GridLanesLayout.cpp
M Source/WebCore/rendering/OrderIterator.cpp
M Source/WebCore/rendering/OrderIterator.h
M Source/WebCore/rendering/RenderBlock.h
M Source/WebCore/rendering/RenderGrid.cpp
M Source/WebCore/rendering/RenderGrid.h
Log Message:
-----------
CSS Grid relayout cost grows quadratically with every grid item with a
distinct 'order'
https://bugs.webkit.org/show_bug.cgi?id=324761
<rdar://173962596>
Reviewed by Sammy Gill.
OrderIterator stores only the set of used `order` values and rebuilt the
sequence by re-
walking the entire sibling chain once per distinct value, so every traversal
cost O(n·k).
Grid paint and hit-testing run it on every repaint, so this has visible user
impact.
This change collects the items once at populate time, sorted by order value,
and exposes
them as a range rather than a stateful cursor. This allows normal iterators to
be used on
the ordered grid items.
A grid whose items all have the initial `order` is already in order-modified
document
order, so the populator skips the sort entirely in that case, and the order
value is
cached next to each item so the sort never reaches back into style. The item
list keeps a
small inline capacity and is emptied with shrink(0) rather than clear(), so a
grid that
relayouts repeatedly reuses its buffer instead of freeing and reallocating it
every time.
Skipped children used to be emitted by the iterator even though they were
marked as
'shouldSkipChild', and hitTestChildren depended on that to hit-test a grid
fieldset's legend.
Now that they are genuinely excluded, hitTestChildren calls
RenderBlock::hitTestExcludedChildrenInBorder in every hit-test phase, after the
grid items,
since the legend paints beneath them. The helper also hit-tests the legend at
the unscrolled
offset in the border box, where it paints.
The item list holds SingleThreadWeakRefs and is cleared by
Grid::setNeedsItemsPlacement(true),
alongside the grid item areas, so a grid item removed from the tree never
remains in it.
On an M4 Max MBP, PerformanceTests/Layout/grid-items-with-distinct-order.html
goes from
~1.2 runs/s to ~63 runs/s.
Test: fast/forms/fieldset/fieldset-grid-legend-hit-test.html
* LayoutTests/fast/forms/fieldset/fieldset-grid-legend-hit-test-expected.txt:
Added.
* LayoutTests/fast/forms/fieldset/fieldset-grid-legend-hit-test.html: Added.
* PerformanceTests/Layout/grid-items-with-distinct-order.html: Added.
* Source/WebCore/SaferCPPExpectations/NoUncheckedPtrMemberCheckerExpectations:
* Source/WebCore/inspector/InspectorOverlay.cpp:
(WebCore::InspectorOverlay::buildGridOverlay):
* Source/WebCore/rendering/Grid.cpp:
(WebCore::Grid::setNeedsItemsPlacement):
(WebCore::Grid::Grid): Deleted.
* Source/WebCore/rendering/Grid.h:
* Source/WebCore/rendering/GridLanesLayout.cpp:
(WebCore::GridLanesLayout::placeGridLanesItems):
* Source/WebCore/rendering/OrderIterator.cpp:
(WebCore::OrderIteratorPopulator::~OrderIteratorPopulator):
(WebCore::OrderIteratorPopulator::collectChild):
(WebCore::OrderIterator::OrderIterator): Deleted.
(WebCore::OrderIterator::first): Deleted.
(WebCore::OrderIterator::next): Deleted.
(WebCore::OrderIterator::reset): Deleted.
(WebCore::OrderIterator::reverse): Deleted.
* Source/WebCore/rendering/OrderIterator.h:
(WebCore::OrderIterator::clear):
(WebCore::OrderIteratorPopulator::OrderIteratorPopulator):
(WebCore::OrderIterator::currentChild const): Deleted.
* Source/WebCore/rendering/RenderBlock.h:
(WebCore::RenderBlock::hitTestInlineChildren):
* Source/WebCore/rendering/RenderGrid.cpp:
(WebCore::RenderGrid::RenderGrid):
(WebCore::RenderGrid::computeIntrinsicLogicalWidths const):
(WebCore::RenderGrid::placeItemsOnGrid):
(WebCore::RenderGrid::paintChildren):
(WebCore::RenderGrid::hitTestChildren):
(WebCore::RenderGrid::GridWrapper::GridWrapper): Deleted.
* Source/WebCore/rendering/RenderGrid.h:
Canonical link: https://commits.webkit.org/321853@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications