How do you build performant lists and grids in Flutter?
TL;DR: Always use ListView.builder / GridView.builder for dynamic lists — they lazily build only visible items. Never use ListView with hundreds of children built eagerly. Add cacheExtent for smoother scrolling. Use SliverList for complex scrollable layouts.
Full Answer
ListView(children: [...]) builds all children at once regardless of visibility. With 500 items, it creates 500 widgets immediately — causing OOM or jank. ListView.builder only creates visible items.
| Aspect | ListView (eager) | ListView.builder (lazy) |
|---|---|---|
| Items built | All at once, upfront | Only visible + cacheExtent |
| Memory | O(n) — grows with list size | O(viewport) — constant |
| Use case | < 20 items, static content | Any dynamic list |
| Item recycling | No — new widget per item | Yes — reuses element slots |
Add const to list item builders when possible. A const widget is never rebuilt — it's the same object reference in the element tree. Critical for items in fast-scrolling lists.
Code Examples
// ListView.builder: ~15 items built at a time // cacheExtent: pre-builds 250px off-screen for smooth scroll // SliverList: same laziness, composable with other slivers
Common Mistakes
- ✗Using ListView(children: longList) — builds all items eagerly, crashes on large datasets
- ✗No key on list items when reordering — Flutter's diffing algorithm reuses wrong element states
Interview Tip
ListView.builder is table stakes Flutter knowledge. Show you also know cacheExtent (pre-renders for smooth scrolling) and when to use SliverList for complex layouts with pinned headers.