Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 6efee9d4dde03e60eb8a23ff8c28708d7e8bd370
      
https://github.com/WebKit/WebKit/commit/6efee9d4dde03e60eb8a23ff8c28708d7e8bd370
  Author: Sammy Gill <[email protected]>
  Date:   2024-12-16 (Mon, 16 Dec 2024)

  Changed paths:
    A PerformanceTests/Layout/nested-grids-single-item-content-change.html
    M Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp
    M Source/WebCore/rendering/RenderGrid.cpp
    M Source/WebCore/rendering/RenderGrid.h

  Log Message:
  -----------
  REGRESSION(281090@main): Sluggish animations on some shopify stores
https://bugs.webkit.org/show_bug.cgi?id=279492
rdar://135791322

Reviewed by Brandon Stewart.

In 281090@main, we added an extra bit of information for the grid to keep track 
of on its
grid items. In particular, we expanded the grid's capabilities to keep track of 
whether or
not any of its grid items needed to perform stretch alignment. This included 
some extra
invalidation inside of GridTrackSizingAlgorithm::logicalHeightForGridItem, as 
performing
layout on a grid item would clear its stretched size.

However, this seems to expose an issue in which we experience thrashing when 
rerunning the
grid layout. This can become an issue because of 2 main aspects of grid layout 
currently:

1.) We rerun the full grid track sizing algorithm each time (i.e. little 
partial layout)
2.) Grid track sizing may need to query the intrinsic sizes of an item. If an 
item was
previously stretched, we will clear that size, compute the intrinsic sizes for 
track
sizing, and then stretch the item again.

These 2 issues unfortunately get compounded in the presence of nested grid 
content.

This patch aims to address 2 by caching the intrinsic logical height of a grid 
item
to try to avoid the adverse effects of recomputing it. This cache will 
specifically be
used to cache the intrinsic logical heights of grid items that are computed 
during the
first pass of row sizing. That means the values that it contains are only valid 
for that
portion of the track sizing algorithm code, and the track sizing algorithm 
should only
populate it with sizes during that step.

Availability -
The cache will live on RenderGrid, which will determine whether or not
it will be available to use by the rest of the code. This availability is 
dependent on the
type of the current grid content. The cache is available to use if none
of the following are true:

1.) The grid is a subgrid

2.) Any of the items are a subgrid

3.) The grid is a masonry grid

4.) Any of the items are being baseline aligned (due to the  intrinsic size 
implications
of baseline-aligned grid items in the spec).

5.) The grid is contained in a fragmented flow.

Invalidation -
If we have an existing cache that is still valid to use during another
pass of layout (i.e. it is still available), then we may need to
invalidate the items.

1.) Before we run grid layout, we will check to see if any of the grid
item renderers have been dirtied. If so, we will then invalidate that
item if it is in the cache and recompute the intrinsic size during the
track sizing algorithm.

2.) If the grid experiences any sort of style mutation, we just
invalidate the entire cache.

3.) During track sizing, we may end up changing the inline constraints
that were used to compute the logical height in a previous pass. If this
is the case, then we need to invalidate the item in the cache as a
different set of constraints may result in a different logical height.

API -
This cache is exposed by RenderGrid via 
intrinsicLogicalHeightsForRowSizingFirstPass()
so that callers can either query, invalidate, or populate it. Callers should 
only expect
to be able to use the cache if it is made available by RenderGrid.

Inside logicalHeightForGridItem, we will check to see if this cache exists and 
if it
contains a value we previously computed for the item. If we do not have a value 
for this
item, we will just compute it and add it to the cache afterwards.

nested-grids-single-item-content-change.html was added as a performance
test to demonstrate the effectiveness of this change. On my M1 Pro MBP,
running this test went from ~950 runs/s to ~1900 runs/s.

* Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:
(WebCore::GridTrackSizingAlgorithmStrategy::logicalHeightForGridItem const):
(WebCore::GridTrackSizingAlgorithmStrategy::minContentContributionForGridItem 
const):
(WebCore::GridTrackSizingAlgorithmStrategy::maxContentContributionForGridItem 
const):
* Source/WebCore/rendering/RenderGrid.cpp:
(WebCore::RenderGrid::styleDidChange):
(WebCore::RenderGrid::layoutGrid):
(WebCore::RenderGrid::isSubgrid const):
(WebCore::RenderGrid::updateIntrinsicLogicalHeightsForRowSizingFirstPassCacheAvailability):
(WebCore::RenderGrid::intrinsicLogicalHeightsForRowSizingFirstPass const):
(WebCore::RenderGrid::canCreateIntrinsicLogicalHeightsForRowSizingFirstPassCache
 const):
(WebCore::GridItemSizeCache::setSizeForGridItem):
(WebCore::GridItemSizeCache::sizeForItem const):
(WebCore::GridItemSizeCache::invalidateSizeForItem):
* Source/WebCore/rendering/RenderGrid.h:

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



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to