[webkit-changes] [WebKit/WebKit] 6efee9: REGRESSION(281090 at main): Sluggish animations on so...

Sammy Gill noreply at github.com
Mon Dec 16 09:49:07 PST 2024


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 6efee9d4dde03e60eb8a23ff8c28708d7e8bd370
      https://github.com/WebKit/WebKit/commit/6efee9d4dde03e60eb8a23ff8c28708d7e8bd370
  Author: Sammy Gill <sammy.gill at apple.com>
  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 at main): Sluggish animations on some shopify stores
https://bugs.webkit.org/show_bug.cgi?id=279492
rdar://135791322

Reviewed by Brandon Stewart.

In 281090 at 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


More information about the webkit-changes mailing list