-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Related: #153085
Update September 2023:
- New SliverVariedExtentList, ListView.extentBuilder for dynamic child sizing on demand
- New caching proposal, follow for updates:
Update from July 2023: #52207 (comment)
Update from September 2021: After much discussion, this #52207 (comment) suggestion emerged as a pretty good proposal. Basically, SliverList could short-circuit actually instantiating and laying out children if, once built, they are discovered to implement the PreferredHeight protocol. The next step is to implement this. -@Hixie
[√] Flutter (Channel master, v1.15.4-pre.241, on Microsoft Windows [Version 10.0.18362.657], locale en-US)
Here is an example (~80 lines) of a 10,000 item ListView, which attempts to uses a simple scrollbar to drive scroll position:
https://gist.github.com/esDotDev/792425c2cdfef947ce514b8ab70511e6
The performance is very poor on all platforms, Desktop, Web, Android, even when using profile mode on Android. iOS has not been tested.
I'm seeing frame render times up to 1300ms on Windows 10, with a Ryzen 3700x. Android, in profile mode, with a Snapdragon 845, has similar results. Visually, you can easily produce a 2-3 second lag by just scrolling up and down a couple of times.
http://screens.gskinner.com/shawn/2020-03-08_12-57-31.mp4
Setting the .itemExtent property solves the problem, but severely limits the flexibility of the list, no expanding cards, no ability to size rows to content, etc.
Problem in a nutshell
We need the ability to have many list items, of variable height, while retaining the ability to set scroll position efficiently. This is especially important on Web and Desktop which typically use scrollbars to traverse lists.
Proposed Solutions
-
It would be nice if the list could handle this itself, seems like it calculates maxExtents each frame, when we really only need it calculating when the size of something has changed. Potentially this could be exposed so we could call it manually (scrollController.calculateExtents()) when we know something is changing.
-
As a simpler workaround, you could expose .maxExtents so I as the programmer of the list can specify max extents with some basic math. ie, if I know my open cards are 40px heigh, and my closed are 20px, I can track open/close cards, and provide the list with the max extents very quickly, without it needing to measure.
-
Could potentially leverage PreferredSizeWidget to reduce the calculation costs for the list. Then each list item can return it's own size, and the developer can come up with novel ways to reduce that calculation cost. For example, I could have my closed items all return a hardcoded value, while my "expanded items" use a LayoutBuilder to calculate their height. Or I could simply have multiple hardcoded values, and return the right one depending on the state of the renderer.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status