Repository navigation
ListView.builder builds unecessary items when using ScrollController #24791
Copy link
Copy link
Closed
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listc: performanceRelates to speed or footprint issues (see "perf:" labels)Relates to speed or footprint issues (see "perf:" labels)f: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagesmaterial_ui package in flutter/packages
Description
When calling the method "jumpTo" on the ScrollController, the ListView builds every item between the current position and the "scrollTo" position;
This code snippet shows the problem. In the log, it will print every item , from 0 to 10000, wich takes a loooong time to run and freezes the entire application.
The desired behavior should be the list building only the last elements of the list.
class TestListViewBuilder extends StatelessWidget {
final _values = List.generate(10000, (index) => index);
final _controller = ScrollController();
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
RaisedButton(
child: Text("Go to bottom"),
onPressed: () {
_controller.jumpTo(_controller.position.maxScrollExtent);
},
),
Expanded(
child: ListView.builder(
controller: _controller,
itemBuilder: (context, index) {
print("Building index $index");
return ListTile(title: Text("Index $index"));
},
itemCount: _values.length,
),
),
],
);
}
}
Flutter doctor:
[√] Flutter (Channel unknown, v0.11.9, on Microsoft Windows [versão 10.0.17134.407], locale pt-BR)
[√] Android toolchain - develop for Android devices (Android SDK 28.0.3)
[√] Android Studio (version 3.2)
[√] IntelliJ IDEA Community Edition (version 2018.3)
[√] Connected device (1 available)
• No issues found!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listc: performanceRelates to speed or footprint issues (see "perf:" labels)Relates to speed or footprint issues (see "perf:" labels)f: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagesmaterial_ui package in flutter/packages
Activity
zoechi commentedon Nov 28, 2018
#21023 looks somewhat related.
HansMuller commentedon Nov 28, 2018
The intermediate list items are built because ListView doesn't now how big they are; so to scroll to the end it needs to layout them all out, one at a time...
You can avoid the problem by specifying
itemExtent, which means that all of the items have the same height. In this caseitemExtent: 56.0should DTRT.shinayser commentedon Nov 28, 2018
But some cases we can't specify the itemExtent, since the item itself has a dynamic height.
Think for example in a log list: a lot of lines of text are being added to it each second. Some lines of text are bigger than others.
HansMuller commentedon Nov 28, 2018
Specifying itemExtent is definitely optional and big lists that contain variable height items are not unusual.
Interactively scrolling a large list of variable height items is efficient because it usually isn't necessary to realize and then discard a large number of items.
Although programmatically scrolling to an arbitrary offset requires computing the size of all of the items between the current offset and the new one, scrolling to the end of a list for which
itemCountis non-null could be made more efficient.shinayser commentedon Nov 28, 2018
So, that mean that it is impossible to do it? There is not another workaround?
HansMuller commentedon Nov 28, 2018
To display very large list of arbitrary sized items that supports scrolling to an arbitrary offset in something like constant time, you'd have to build a custom scrolling container that could take advantage of app-specific constraints that applied to the distribution of item sizes.
zoechi commentedon Nov 29, 2018
#12319 is about scrolling to an index
veenatic82 commentedon Sep 14, 2019
I am even seeing this happen when you set a PageStorageKey to a CustomScrollView. Switch back to the same widget and when flutter tries to preserve the scroll position, it builds all the items from the beginning. So, if you had 5000 items in your ScrollView, and you are at 4998th one, for example, it is rebuilding all items from the beginning till 4998th item. Also, during that process, I am seeing an increased memory pressure, like its shoots memory usage from say 15mb to 400 mb and when you scroll up or down for some time, it comes back to normal. But I think on devices where memory is limited, you may see Out Of memory exception. I tested with very small items say 50 characters each. So, if you have images or more stuff on each item, surely memory can shoot event more.
I think we need to have a solution for this. Any plans on fixing this?
VladyslavBondarenko commentedon Apr 2, 2020
Persists with
dev v1.16.4-pre.33esDotDev commentedon Apr 2, 2020
It feels like there is a middle ground here, a non app-specific method where the app-developer could aid the list in it's calculations... Anything to avoid doing a full build and layout pass on each element.
Thinking something like a measure function we could provide.
App developers could then come up with novel ways of calculating our expected heights, without the list needing to actually lay everything out, and without developers having to build a custom list.
For example in the log example above, I could wrap my list in a LayoutBuilder, and then (using maxWidth, characterWidth, string.length and lineHeight, all of which are known to me) I could fairly easily calculate the height for each item (assuming monospace font)
Note that this will become more and more of an issue, as Desktop and Web apps roll out, with scrollbars that use JumpTo constantly with very large delta's ( as opposed to finger scrolling which just naturally avoids this issue )
liyuqian commentedon Jul 21, 2020
This seems to be the same issue as #52207
VladyslavBondarenko commentedon Jul 27, 2020
Please follow up on #52207,
closing current issue as duplicate,
if you disagree please write in the comments and I will reopen it
github-actions commentedon Aug 14, 2021
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.