Skip to content

[two_dimensional_scrollables] Fix tableview janks when first row/column pinned#180563

Merged
auto-submit[bot] merged 8 commits intoflutter:masterfrom
wangfeihang:fix_tableview_janks
Mar 3, 2026
Merged

[two_dimensional_scrollables] Fix tableview janks when first row/column pinned#180563
auto-submit[bot] merged 8 commits intoflutter:masterfrom
wangfeihang:fix_tableview_janks

Conversation

@wangfeihang
Copy link
Contributor

@wangfeihang wangfeihang commented Jan 6, 2026

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

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@fluttergithubbot
Copy link
Contributor

An existing Git SHA, 31a62a0cccf7f7578d39b1d817329bc802551b4b, was detected, and no actions were taken.

To re-trigger presubmits after closing or re-opeing a PR, or pushing a HEAD commit (i.e. with --force) that already was pushed before, push a blank commit (git commit --allow-empty -m "Trigger Build") or rebase to continue.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. labels Jan 6, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@wangfeihang wangfeihang changed the title Fix tableview janks [two_dimensional_scrollables] Fix tableview janks when first row/column pinned Jan 7, 2026
@wangfeihang
Copy link
Contributor Author

@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!

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution! 💙

@wangfeihang
Copy link
Contributor Author

@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.

@Piinks
Copy link
Contributor

Piinks commented Jan 14, 2026

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.

@wangfeihang wangfeihang requested a review from Piinks January 15, 2026 06:16
@Piinks Piinks force-pushed the fix_tableview_janks branch from c350efa to cb2b83e Compare February 3, 2026 18:16
Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the updates and your patience. This LGTM. It will need a second reviewer, I have requested one. 💙

Copy link
Contributor

@Renzo-Olivares Renzo-Olivares left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM w/ small nits, thank you for the contribution!

Copy link
Contributor

@Renzo-Olivares Renzo-Olivares left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RE-LGTM

…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
@Renzo-Olivares Renzo-Olivares added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 2, 2026
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Mar 3, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 3, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 3, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 3, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 4, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 4, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 4, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 4, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 4, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 4, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 5, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 5, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 5, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 5, 2026
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Mar 5, 2026
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:
...
xxxOVALxxx pushed a commit to xxxOVALxxx/flutter that referenced this pull request Mar 10, 2026
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants