Repository navigation
RenderSliverMainAxisGroup causes lazy children to build eagerly #142183
Description
Steps to reproduce
Add a CustomScrollView with SliverMainAxisGroups with SliverLists or SliverGrids inside. Add a simple print in the lists' item builders to print the list and item indices. Rather only the visible and first item, all or most children are instantiated during the first layout pass, even for groups far below the visible extent.
For the minimal example below, the consequences are less severe, with only 10 or so built per group, but with several groups each with a sticky SliverPersistentHeader and a SliverGrid of images to be fetched for each child, there is a quite significant performance hit (and no way to keep all those images in memory at the same time).
My investigation led me to a missing cacheExtent update in the RenderSliverMainAxisGroup's performLayout, causing it to consume no cache extent, even though it's children would. As the layout progresses, each RenderSliverMainAxisGroup has the same cacheExtent set, as it is never decreased in between.
Adding the following at the end of performLayout, in sliver_group.dart line 287, seems to fix it for me:
final double paintExtent = calculatePaintOffset(
constraints,
from: math.min(constraints.scrollOffset, 0),
to: totalScrollExtent,
);
geometry = SliverGeometry(
scrollExtent: totalScrollExtent,
paintExtent: paintExtent,
cacheExtent: paintExtent,
maxPaintExtent: maxPaintExtent,
hasVisualOverflow: totalScrollExtent > constraints.remainingPaintExtent ||
constraints.scrollOffset > 0.0,
);
}
Expected results
The children of any lists in view, and the first child for any subsequent lists should be built and laid out (for calculating max extent etc).
Actual results
All (or several) children for each list gets built immediately, regardless of whether the children or even lists are visible.
Code sample
Code sample
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: const NonLazySliverGrids(),
);
}
}
class NonLazySliverGrids extends StatelessWidget {
const NonLazySliverGrids({super.key});
@override
Widget build(BuildContext context) => CustomScrollView(
slivers: [
for (var i = 0; i < 100; i++)
SliverMainAxisGroup(
slivers: [
SliverList.builder(
itemCount: 100,
itemBuilder: (context, index) {
print('list $i, item $index');
return Container(
height: 24,
color: Colors.primaries[index % Colors.primaries.length],
);
},
),
],
),
],
);
}Screenshots or Video
No response
Logs
No response
Flutter Doctor output
Doctor output
[√] Flutter (Channel stable, 3.16.8, on Microsoft Windows [Version 10.0.22631.3007], locale en-US)
• Flutter version 3.16.8 on channel stable at C:\src\flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 67457e669f (8 days ago), 2024-01-16 16:22:29 -0800
• Engine revision 6e2ea58a5c
• Dart version 3.2.5
• DevTools version 2.28.5
[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at C:\Users\~\AppData\Local\Android\sdk
• Platform android-34, build-tools 34.0.0
• Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
• Java version OpenJDK Runtime Environment (build 17.0.7+0-b2043.56-10550314)
• All Android licenses accepted.
[√] Chrome - develop for the web
• Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
[√] Visual Studio - develop Windows apps (Visual Studio Build Tools 2022 17.7.6)
• Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools
• Visual Studio Build Tools 2022 version 17.7.34221.43
• Windows 10 SDK version 10.0.22621.0
[√] Android Studio (version 2023.1)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.7+0-b2043.56-10550314)
[√] VS Code (version 1.85.2)
• VS Code at C:\Users\~\AppData\Local\Programs\Microsoft VS Code
• Flutter extension version 3.80.0
[√] Connected device (3 available)
• Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.22631.3007]
• Chrome (web) • chrome • web-javascript • Google Chrome 120.0.6099.225
• Edge (web) • edge • web-javascript • Microsoft Edge 120.0.2210.144
[√] Network resources
• All expected network resources are available.
• No issues found!
Activity
huycozy commentedon Jan 25, 2024
Thanks for the report. I can see all SliverList's items are instantiated on all SliverMainAxisGroup(s). Attaching a recorded video and updated sample code to see the issue more clearly.
Screen.Recording.2024-01-25.at.16.52.02.mp4
Sample code
flutter doctor -v (stable and master)
[✓] Flutter (Channel stable, 3.16.8, on macOS 14.1 23B74 darwin-x64, locale en-VN) • Flutter version 3.16.8 on channel stable at /Users/huynq/Documents/GitHub/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 67457e669f (27 hours ago), 2024-01-16 16:22:29 -0800 • Engine revision 6e2ea58a5c • Dart version 3.2.5 • DevTools version 2.28.5 [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at /Users/huynq/Library/Android/sdk • Platform android-34, build-tools 34.0.0 • ANDROID_HOME = /Users/huynq/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 15.0.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 15A507 • CocoaPods version 1.14.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2023.1) • Android Studio at /Applications/Android Studio Hedgehog.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314) [✓] Android Studio (version 2022.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • android-studio-dir = /Applications/Android Studio.app/ • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694) [✓] VS Code (version 1.85.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.80.0 [✓] Connected device (3 available) • iPhone (mobile) • d9a94afe2b649fef56ba0bfeb052f0f2a7dae95e • ios • iOS 15.8 19H370 • macOS (desktop) • macos • darwin-x64 • macOS 14.1 23B74 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 120.0.6099.234 [✓] Network resources • All expected network resources are available. • No issues found!Fix SliverMainAxisGroup geometry cacheExtent (#142482)
github-actions commentedon Feb 14, 2024
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.