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

Reply via email to