I'm loading data from a Firebase collection into Listview of Cards. The problem is when I try to scroll I encounter micro stutters. They usually happen just as a new Card is about to appear in the view. It is happening in the web release build on both MacOS and IOS.
This is my code:
class MyGameList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: FirebaseFirestore.instance.collection('games').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot data = snapshot.data!.docs[index];
return GameCard(
anim: data['anim'],
name: data['name'],
tags: List<String>.from(data['tags'] ?? []),
dropdownValue: data['dropdownValue'],
year: data['year'],
minutes: data['minutes'],
goal: data['goal'],
rules: data['rules'],
responsibility: data['responsibility'],
props: data['props'],
good: data['good'],
bad: data['bad'],
);
},
);
},
);
}
}
When I try to manually generate data and create Listview of Cards from it, it works much better and scrolling is almost flawless.
This is the code for generated data:
class MyTestGameList extends StatelessWidget {
final List<Map<String, dynamic>> gamesData = List.generate(
100, // Generates 100 items for test
(index) => {
'anim': 'Animator $index',
'name': 'Game $index',
'tags': ['Tag1', 'Tag2'],
'dropdownValue': 'Camp $index',
'year': '202${index % 10}',
'minutes': '${20 + index}',
'goal': 'Goal of Game $index'*2,
'rules': 'Rules of Game $index'*20,
'responsibility': 'Responsibility in Game $index'*3,
'props': 'Props for Game $index'*2,
'good': 'Good aspects of Game $index'*5,
'bad': 'Improvements for Game $index'*5,
},
);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: gamesData.length,
itemBuilder: (context, index) {
var game = gamesData[index];
return GameCard(
anim: game['anim'],
name: game['name'],
tags: game['tags'],
dropdownValue: game['dropdownValue'],
year: game['year'],
minutes: game['minutes'],
goal: game['goal'],
rules: game['rules'],
responsibility: game['responsibility'],
props: game['props'],
good: game['good'],
bad: game['bad'],
);
},
);
}
}
Am I doing something fundamentally wrong? My cards contain no images and just a bit of text. I even tried building with canvaskit which didn't help.