WPF DataGrid Performance at Scale
If your WPF DataGrid starts to hitch the moment you hit a few hundred thousand rows, the bottleneck isn’t just “too much data”—it’s how the grid handles it. Async data virtualization and row recycling eliminate UI stalls by keeping the render thread free while data loads in the background.
What causes freezes in WPF grids
- Synchronous data fetches on the UI thread
- Excessive layout passes during fast scroll
- Row template churn without recycling
- Binding overhead from heavyweight cell templates
Our test setup
- Dataset: 1,000,000 rows, mixed column types, server-side filter capability
- Interactions: fast scroll (mouse + scrollbar), multi-column group, filter text entry
- Environment: Release build, x64, .NET 8, hardware acceleration enabled
What changed with async virtualization
- Data requests happen off the UI thread
- Rows recycle; visual tree churn is minimized
- Placeholders render immediately; data fills progressively
- Input stays responsive even under heavy fetch
Expected performance profile
- Scrolling retains visual continuity with stable 60 FPS
- Input latency stays under ~50 ms while data loads
- Memory usage remains bounded due to page/windowing
Implementation pattern (simplified)
- Use an async-friendly collection and page/window manager
- Kick off data fetch on background threads
- Bind to virtualization-aware views
- Enable row recycling and lightweight cell templates
Developer checklist
- Turn on row virtualization and recycling
- Move data fetches off the UI thread
- Use lightweight cell templates and value converters sparingly
- Group/filter via async-capable, incremental sources
- Measure with ETW/WPA to confirm UI thread headroom
Why it matters
Users feel stutter more than they notice raw milliseconds. Smoothness is the difference between “good enough” and “we’re buying this.”
Try Xceed DataGrid for WPF with async virtualization and see the difference in under an hour. Start your 45-day trial:
FAQ
Does async virtualization work with grouping and filtering?
Yes—use incremental sources so group/filters compute off the UI thread and hydrate progressively.
Will virtualization change my data model?
No; you wrap sources in a virtualization-aware layer.
How do I measure if it’s working?
Profile UI thread time with ETW/WPA; you should see input/render threads with headroom during fast scroll.