The day a 10,000-row Excel file broke our React application.
Recently, I worked on a feature that seemed straightforward.
Users could upload an Excel file, review the data in an editable table, fix validation errors, and submit it.
It worked perfectly during development.
Until someone uploaded a file with 10,000+ records.
Within seconds:
❌ The UI became unresponsive.
❌ Scrolling was painfully slow.
❌ Typing into a single field lagged.
❌ Chrome started warning that the page was unresponsive.
At first, we investigated our API calls and backend processing.
Surprisingly, they weren’t the bottleneck.
The real issue was the frontend.
We were rendering every single row as editable React components — even though users could only see about 20–30 rows at a time.
That meant thousands of DOM nodes, form controls, event listeners, and validation states living in memory simultaneously.
Then came the bigger UX challenge…
If the uploaded file contained validation errors, users had to locate the problematic rows manually.
Imagine receiving an error for row 8,742.
The only option was to scroll through thousands of rows until you found it.
It wasn’t just slow — it was frustrating.
The solution: List Virtualization
Instead of rendering all 10,000 rows, we rendered only the rows currently visible in the viewport.
As users scrolled:
- Rows leaving the screen were recycled.
- New rows were rendered on demand.
- The number of mounted components stayed almost constant.
The result?
✅ Smooth scrolling
✅ Responsive editing
Get Saniyasuhail’s stories in your inbox
Join Medium for free to get updates from this writer.
✅ Significantly lower memory usage
How It Works Internally
Virtualization libraries typically:
- Measure the scroll position.
- Calculate which items should be visible.
- Render only those items.
- Position them correctly inside a container that represents the full list height.
- Update the rendered window as the user scrolls.
To the user, the list appears complete even though most rows don’t exist in the DOM at any moment.
Implementing Virtualization with react-window
Install the library:
npm install react-windowExample:
import { FixedSizeList } from "react-window";
const Row = ({ index, style }) => (
<div style={style}>
User {index}
</div>
);
export default function App() {
return (
<FixedSizeList
height={500}
width={400}
itemSize={40}
itemCount={100000}
>
{Row}
</FixedSizeList>
);
}We also improved the experience by:
- Automatically scrolling to the first validation error.
- Highlighting invalid rows.
- Adding quick navigation between errors instead of forcing users to hunt through thousands of records.
My biggest takeaway
This experience reminded me that performance isn’t just about making an application faster.
It’s about removing friction for users.
Virtualization solved the technical bottleneck, but improving error navigation solved the usability problem.
Both were equally important.
When Should You Use Virtualization?
Virtualization is a great fit for:
- Admin dashboards
- Data tables
- Analytics platforms
- Log viewers
- Email clients
- Chat history
- File explorers
- Inventory systems
When You Might Not Need It
Virtualization isn’t always necessary. For small lists (for example, a few dozen items), the added complexity may outweigh the benefits. It also requires extra care when:
- Supporting variable-height rows.
- Implementing browser search (Ctrl+F), since off-screen items aren’t in the DOM.
- Printing pages, where all content may need to be rendered.
- Maintaining accessibility, as assistive technologies may interact differently with virtualized content.
Evaluate your use case before introducing it.
Have you faced a similar challenge while working with large datasets? I’d love to hear how you approached it.
#React #Frontend #JavaScript #Performance #WebDevelopment #Engineering #ReactJS #SoftwareEngineering #Optimization #Tech





