// measured, not promised
The stress test
is on this page.
One million rows are loaded into the grid below — right now, in your browser. Scroll it as hard as you can and watch the frame meter.
Rows are generated on demand — only the visible window ever exists in the DOM. The frame meter is a plain requestAnimationFrame counter, measured live on your machine.
Methodology
How are the million rows loaded?
The data source generates rows deterministically from the row index, on demand. The grid requests only the window the viewport needs (60 rows at a time), so total memory stays flat no matter how far you scroll.
What does the fps meter measure?
A requestAnimationFrame loop counts frames rendered by your browser over each second, on your hardware, while this page runs. It is not a recording and not a lab number.
How is the bundle size measured?
The production build is minified and gzipped — the same transformation your app bundler applies — giving 170.4 KB (112.3 KB with Brotli). The number is produced by a script and checked in continuous integration on every change, so it can never silently drift; the library also adds zero third-party runtime dependencies to your install.
Why virtual scroll instead of pagination tricks?
Only visible rows enter the DOM, positioned with binary-search scroll mapping. Row components are recycled, change detection is OnPush + signals, and no layout thrash occurs at any scroll speed — continuously verified: scrolling ten thousand rows keeps the DOM a bounded window and does at most one layout per scroll step.