Repository navigation
zero-swift: measure only the virtual list's rows near the viewport - #25
Merged
Merged
Conversation
A layout pass made and measured a cell for every loaded row: after the first sync, 50 rows while 11 were visible (460-682 ms on zbugs-swift). LayoutHost now measures only rows within one viewport height above and below the viewport. Other rows use their last measured height, or the estimated row height, until they come that near. While a jump or a restore is landing, it measures every row, because where it lands depends on the rows above. A row above the viewport that is measured at a height other than its estimate goes through the same compensation as a row changing height, in the same pass, so rows on screen hold still. A scroll to rows not yet measured lays out again in the same pass. A jump to a loaded row that scrolled is lined up again in that pass, now measured, before it lands. Amp-Thread-ID: https://ampcode.com/threads/T-c513a037-a257-45e0-b9a9-15c15edfe859 Co-authored-by: tmm <tmm@tmm.dev>
… 0.2 s On a slow CI runner the layout pass that places the highlight can run after 0.2 s; the test now polls up to 5 s, then checks as before. Amp-Thread-ID: https://ampcode.com/threads/T-c513a037-a257-45e0-b9a9-15c15edfe859 Co-authored-by: tmm <tmm@tmm.dev>
When a stalled frame holds a jump's landing past the script's pause, the next phase used to end the unmoved jump and check its landing frame as an ordinary frame of that phase, flagging it as wrong. A jump that hasn't moved when a phase begins now takes the next frame and ends with it. The wrong-frame checks are unchanged. Amp-Thread-ID: https://ampcode.com/threads/T-c513a037-a257-45e0-b9a9-15c15edfe859 Co-authored-by: tmm <tmm@tmm.dev>
…t, not 0 Resized from 0 high at a fractional list offset, as when lazy measuring makes a view mid-scroll, a row view's autoresizing subviews came out that fraction of a point above it, which a 1x display rounds to a whole point for the view's life. Amp-Thread-ID: https://ampcode.com/threads/T-c513a037-a257-45e0-b9a9-15c15edfe859 Co-authored-by: tmm <tmm@tmm.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
After zbugs' first sync, the list's first layout pass created and measured all 50 loaded rows through SwiftUI, when 11 were visible: 460–680 ms on the main thread (iPhone simulator, Debug, low CPU priority). Together with applying the first poke, that stall makes XCTest's accessibility queries time out on slow CI runners.
What changed:
LayoutHostcreates and measures only rows within one viewport height above and below the viewport. Other rows keep their last measured height, or the estimated row height, until they come near.measureAndCompensatepath keeps them still in the same pass, as for any row changing height. Mid-list it adjusts the space before the rows; near the start it scrolls.VirtualizerCore.land(), on a host that lays out with its scroll, a row jump that scrolled lands again in the next pass with the row measured. Without this,.end/.centerjumps drifted.invalidateHeights()).Tests: 4 new
LayoutHostTests. The first fails on the old code:One existing test now compares against the user's scroll target rather than the post-compensation offset.
Not yet verified: the UIKit and AppKit parts (
RowsScrollView,VirtualList) were changed without running them. The virtual-list UI suites run in CI, and they'll also run on a Mac before merging.Tested on Linux: 215 Swift tests,
swift format lint --strict, and the zbugs-swift build.