[two_dimensional_scrollables] Fix tableview janks when first row/column pinned#180563
Conversation
|
An existing Git SHA, To re-trigger presubmits after closing or re-opeing a PR, or pushing a HEAD commit (i.e. with |
There was a problem hiding this comment.
Code Review
This pull request effectively addresses a performance issue in RenderTwoDimensionalViewport by optimizing the child iteration logic in _reifyChildren. Instead of iterating over all children, the new implementation collects only the visible ones and processes them, which significantly improves performance for large tables with pinned rows or columns. The accompanying test case thoroughly validates that the sorting order of children remains correct after this refactoring. The changes are well-implemented and directly target the described problem. I have one minor suggestion to improve code conciseness.
|
@Piinks Hi Piinks, I've submitted a PR to fix the jank issue that occurs when the first row and first column of the tableview are pinned. Could you please help review it? Thanks a lot! |
packages/flutter/test/widgets/two_dimensional_viewport_test.dart
Outdated
Show resolved
Hide resolved
Piinks
left a comment
There was a problem hiding this comment.
Thanks for the contribution! 💙
|
@Piinks Hi Piinks, I’ve updated the code according to the review feedback. I noticed that there hasn’t been any new progress on this PR lately. Is there anything I can do to help get it merged? Sorry for the bother. |
No worries at all. We're still catching up on the PR backlog from the holidays. |
c350efa to
cb2b83e
Compare
Piinks
left a comment
There was a problem hiding this comment.
Thank you for the updates and your patience. This LGTM. It will need a second reviewer, I have requested one. 💙
Renzo-Olivares
left a comment
There was a problem hiding this comment.
LGTM w/ small nits, thank you for the contribution!
packages/flutter/test/widgets/two_dimensional_viewport_test.dart
Outdated
Show resolved
Hide resolved
packages/flutter/test/widgets/two_dimensional_viewport_test.dart
Outdated
Show resolved
Hide resolved
…ing lag when scrolling to row 15,000 with pinned first row and column
…ing lag when scrolling to row 15,000 with pinned first row and column
…ing lag when scrolling to row 15,000 with pinned first row and column
…ing lag when scrolling to row 15,000 with pinned first row and column, fix flutter analisys failure.
…ing lag when scrolling to row 15,000 with pinned first row and column, fix format
…ing lag when scrolling to row 15,000 with pinned first row and column, unused member variables.
…ing lag when scrolling to row 15,000 with pinned first row and column, remove unused import.
…ing lag when scrolling to row 15,000 with pinned first row and column, add period to comments
a5b826f to
7cef22e
Compare
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
…t row/column pinned (flutter/flutter#180563)
Roll Flutter from 46fb7210422d to d3dd7744e81f (33 revisions) flutter/flutter@46fb721...d3dd774 2026-03-04 [email protected] Show warning when plugins do not support SwiftPM (flutter/flutter#182506) 2026-03-04 [email protected] Give guided message when project is not compatible with SwiftPM (flutter/flutter#182394) 2026-03-04 [email protected] Pass --web-define through to web runner when using --machine mode (flutter/flutter#183228) 2026-03-04 [email protected] Improve SwiftPM minimum platform mismatch diagnostics (flutter/flutter#182375) 2026-03-04 [email protected] Use dart::bin::SetupDartIo to setup dart:io (flutter/flutter#176714) 2026-03-04 [email protected] Roll Skia from 3197848b14ad to ada0b7628c79 (5 revisions) (flutter/flutter#183221) 2026-03-04 [email protected] Roll Skia from fe9e9f22c531 to 3197848b14ad (15 revisions) (flutter/flutter#183198) 2026-03-04 [email protected] refactor: remove material in reorderable_list_test, scroll_notification_test, scroll_physics_test, shortcuts_test, sliver_floating_header_test, snapshot_widget_test (flutter/flutter#182698) 2026-03-04 [email protected] refactor: remove material in pop_scope_test, route_notification_message_test, two_dimensional_utils, two_dimensional_viewport_test (flutter/flutter#182699) 2026-03-04 [email protected] Add dev/benchmarks/README.md (flutter/flutter#182976) 2026-03-03 [email protected] Roll RapidJSON to a branch based on the current upstream head (flutter/flutter#183048) 2026-03-03 [email protected] [Impeller] Update comments to reflect new info about 2-pass rendering (flutter/flutter#183050) 2026-03-03 [email protected] Add vmservices for accessibilityEvaluation (flutter/flutter#182791) 2026-03-03 [email protected] Roll Fuchsia Linux SDK from 0dCDM2oORHwDf_pyb... to JJw5EJ87vLGqFVl4h... (flutter/flutter#183177) 2026-03-03 [email protected] Support mixed color spaces in `Color.lerp` (flutter/flutter#182934) 2026-03-03 [email protected] Add warning when there is a widget with color between `Material` and `ListTile` (flutter/flutter#181402) 2026-03-03 [email protected] [ios]uitest for admob banner in scrollable list gesture issue (flutter/flutter#183128) 2026-03-03 [email protected] Roll Packages from faa4e22 to 9083bc9 (4 revisions) (flutter/flutter#183164) 2026-03-03 [email protected] Build App and native asset frameworks for Add to App FlutterPluginRegistrant (flutter/flutter#183136) 2026-03-03 [email protected] Roll Skia from f886711f180d to fe9e9f22c531 (4 revisions) (flutter/flutter#183155) 2026-03-03 [email protected] Roll Dart SDK from e86dbe9aa742 to c597ef90d2dc (2 revisions) (flutter/flutter#183147) 2026-03-03 [email protected] fix: bump matcher (flutter/flutter#183167) 2026-03-02 [email protected] Use isA to test for exceptions (flutter/flutter#183129) 2026-03-02 [email protected] [two_dimensional_scrollables] Fix tableview janks when first row/column pinned (flutter/flutter#180563) 2026-03-02 [email protected] Add await to callsites of BasicMessageChannel.send (flutter/flutter#182868) 2026-03-02 [email protected] Roll pub packages (flutter/flutter#183133) 2026-03-02 [email protected] Improve FFI code for windowing (flutter/flutter#183098) 2026-03-02 [email protected] [workflow] Update the changelog merge action to fetch the stable branch (flutter/flutter#183132) 2026-03-02 [email protected] Roll Skia from e180358b7a7a to f886711f180d (2 revisions) (flutter/flutter#183130) 2026-03-02 [email protected] Merge changelog from 3.41.3. (flutter/flutter#183131) 2026-03-02 [email protected] Make TextDecoration final and unify maskValue across platforms (flutter/flutter#183070) 2026-03-02 [email protected] Roll pub packages (flutter/flutter#182640) 2026-03-02 [email protected] Enable SwiftPM by default on master and beta (flutter/flutter#182923) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: ...
…mn pinned (flutter#180563) ### Description This PR addresses a critical performance issue where the TableView component experiences severe lag when scrolling to row 15,000 with both the first row and first column pinned. ### Root Cause The _reifyChildren method in RenderTwoDimensionalViewport was consuming excessive CPU resources due to inefficient iteration logic: It used nested for-loops starting from index 0, iterating through all rows (0 ~ 15K) even when only 4 rows/columns were visible on screen The pinned first row/column caused unnecessary full-range iteration instead of limiting to the visible viewport ### Solution Optimized the iteration logic in _reifyChildren: Store only viewport-visible children in _currentChildVicinities Restrict ParentData calculations in _reifyChildren to only the children within _currentChildVicinities Eliminated full-range (0 ~ 15K) iterations and focused only on visible elements ### Fixes:flutter#138271 Important Note: This fix exclusively resolves the jank associated with pinned rows and columns; the jank in non-pinned scenarios stems from a different root cause and is not included in this commit. ### Video performance comparison before: https://github.com/user-attachments/assets/b0892dd5-858b-44a6-8f26-37803ce50452 after: https://github.com/user-attachments/assets/7a6cddf2-04bf-465d-9997-3fdcab5692f7 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
Description
This PR addresses a critical performance issue where the TableView component experiences severe lag when scrolling to row 15,000 with both the first row and first column pinned.
Root Cause
The _reifyChildren method in RenderTwoDimensionalViewport was consuming excessive CPU resources due to inefficient iteration logic:
It used nested for-loops starting from index 0, iterating through all rows (0 ~ 15K) even when only 4 rows/columns were visible on screen
The pinned first row/column caused unnecessary full-range iteration instead of limiting to the visible viewport
Solution
Optimized the iteration logic in _reifyChildren:
Store only viewport-visible children in _currentChildVicinities
Restrict ParentData calculations in _reifyChildren to only the children within _currentChildVicinities
Eliminated full-range (0 ~ 15K) iterations and focused only on visible elements
Fixes:#138271
Important Note: This fix exclusively resolves the jank associated with pinned rows and columns; the jank in non-pinned scenarios stems from a different root cause and is not included in this commit.
Video performance comparison
before:
https://github.com/user-attachments/assets/b0892dd5-858b-44a6-8f26-37803ce50452
after:
https://github.com/user-attachments/assets/7a6cddf2-04bf-465d-9997-3fdcab5692f7
Pre-launch Checklist
///).