Optimizing Flutter ListView Performance with itemExtent
Learn how to eliminate Flutter scroll lag using ListView.builder and itemExtent to bypass expensive layout measurements in high-performance lists.
27 Feb 2026, 04:53 UTC

When building long lists in Flutter, the most common performance bottleneck is 'jank' caused by the engine measuring every item as it enters the viewport. To achieve smooth scrolling with thousands of rows, use ListView.builder combined with the itemExtent property. This allows the scroll engine to skip the layout phase for offscreen children by calculating positions mathematically rather than through real-time measurement.
The Mechanism of Lazy Construction
Normally, ListView.builder only constructs the widgets that are currently visible in the viewport. However, without a fixed height, Flutter must measure each child widget to determine the total scrollable area and where the next item begins. If you provide itemExtent, you tell the framework exactly how many pixels each row occupies. The engine can then calculate the total height and the scroll offset of any item instantly without executing the build method of hidden widgets.
Configuration Example
The following example demonstrates a high-performance list where each row is exactly 72 pixels high. Using ValueKey ensures that if the list order changes, Flutter maintains the state of the correct widget.
ListView.builder(
itemCount: rows.length,
itemExtent: 72.0, // Fixed height in pixels
padding: const EdgeInsets.all(8.0),
itemBuilder: (context, index) {
final row = rows[index];
return ListTile(
key: ValueKey(row.id), // Stable key for state management
title: Text(row.title),
subtitle: Text(row.description),
);
},
);
Critical Constraints and Common Pitfalls
- Variable Heights: Do not use
itemExtentif your rows have dynamic text or elements that change height based. If a child exceeds the extent, it will be clipped unexpectedly, or layout overflows may occur. - The shrinkWrap Trap: Avoid using
shrinkWrap: trueon long lists. This property forces the list to calculate every single child height to determine the list's total height, effectively defeating the benefits of lazy loading and causing CPU spikes. - Nested Scrollables: Never place a vertical
ListViewinside a verticalColumnwithout a fixed height. UseCustomScrollViewwithSliverListinstead to manage multiple scrolling areas. - Index-based Keys: When lists are reorderable, never use the list index as a key. If an item is removed from the top, the indices shift, and Flutter may apply the state of the wrong widget. Always use unique IDs from your data model.
Verifying Performance
Performance metrics in Debug mode are unreliable because the overhead of the debugger masks layout issues. To verify your list is optimized:
- Run the app using
flutter run --profile. - Open the Flutter DevTools and navigate to the Performance tab.
- Scroll the list rapidly. Monitor the 'Build' and 'Raster' frames. If they stay consistently under 16ms (for 60Hz) or 8ms (for 120Hz), your list is efficient.
- Check for 'white flashes' during fast flings; if they appear, increase the
cacheExtentproperty to pre-render more offscreen items.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.