LogoTRUONG PHAM
Home
Projects
Blogs
YouTube
Contact

Newsletter

Stay updated with technical artifacts and engineering insights.

LogoTRUONG PHAM

Building scalable software and sharing insights on technology & life.

Sitemap

  • Home
  • Projects
  • Blogs
  • YouTube
  • Contact

Connect

  • GitHub
  • LinkedIn
  • Email
  • YouTube

© 2024 TRUONG PHAM. © All rights reserved.

Privacy PolicyTerms of Service
Back
Blog #15: The 10,000-Row Lesson – When Table Virtualization saved my career
50 FRONTEND LESSONS – HARD-EARNED EXPERIENCES

Blog #15: The 10,000-Row Lesson – When Table Virtualization saved my career

To my early large-data days, when rendering 5000 rows of data literally made the browser smoke.

TP
Truong PhamSoftware Engineer
PublishedApril 20, 2024

Hey there, my younger, "fiery" self from a few years ago.

I remember when the boss tasked you with displaying the entire inventory of a supermarket chain—about 15,000 items. You smiled confidently: "Easy, boss, I'll just use map() and it's done!". You excitedly coded, and sure enough, locally with 10 test rows, it ran lightning fast. You happily deployed to Production.

But when the real 15,000-row data flooded in, your browser suddenly froze. The mouse wouldn't move even 1mm. Google Chrome reported "Out of Memory" and crashed the computers of dozens of warehouse staff. You turned pale, not understanding what you'd done wrong when the "code was clearly correct in logic."

1. Simple Explanation: The Story of an Endless List

Imagine you're standing and reading a list of 15,000 names. Your old way was: Spread the entire 3km-long paper on the ground and try to see everything at once. The browser is the one who has to "draw" all 15,000 names into memory. Each name is a set of HTML tags (div, span, tr, td). 15,000 rows multiplied by 10 columns—you just forced the browser to manage 150,000 DOM nodes. That's an overwhelming burden for any computer.

2. Current Perspective: Why Virtualization is a Miracle?

The truth is: human eyes can only see about 10-20 rows on the screen at a time. So why do we have to draw the 14,980 rows that the user hasn't seen (or will never see)?

Virtualization works on an extremely smart principle:

  • You draw only the 20 rows currently visible.
  • As the user scrolls down, you quickly "reuse" old rows, replace them with new data, and push them down.
  • The user still sees an incredibly long scrollbar (thanks to a hollow div tag with height equal to 15,000 rows), but in reality, the browser memory only has to carry 20-30 HTML tags.

3. Concrete Example: The map() method trap

You used to write like this:

// Junior's way: "All-in-one" and shutdown
const BigTable = ({ data }) => {
  return (
    <div className="table-container">
      {data.map(item => (
        <Row key={item.id} {...item} /> 
        // 15,000 components initialized at once!
      ))}
    </div>
  );
};

Why is this a problem? Because even when you can't see everything, the browser still has to calculate layout and style and manage events for every node. Just one keystroke in the search bar, and React will have to compare those 15,000 nodes. Lag is inevitable.

Sustainable Approach (Virtual List):

import { FixedSizeList as List } from 'react-window';

const BigTable = ({ data }) => {
  const Row = ({ index, style }) => (
    <div style={style}>
      {index}: {data[index].name}
    </div>
  );

  return (
    <List
      height={600}
      itemCount={data.length}
      itemSize={35}
      width={1000}
    >
      {Row} 
      {/* Renders only about 15-20 Rows at any given time */}
    </List>
  );
};

4. Comparison: "Doing it Fast" vs "Doing it Sustainably"

CriteriaDoing it Fast (Direct Map)Doing it Sustainably (Virtualization)
Ease of implementationVery easy, everyone knows howNeeds a library or writing scroll calculation logic
PerformanceGood with < 100 rows, disaster with > 1000Always blazing fast, even with 1 million rows
Memory (RAM)Skyrockets with data volumeAlways stays stable and low
Typing/Scrolling experienceLaggy, delayedSmooth as silk (60 FPS)

Juniors often say: "Data will probably never reach 1000 rows". But a Senior always prepares for the worst-case scenario: If data grows to 100,000 rows, will my code still survive?

5. Practical Lesson: "Virtual" but Real

I once saved a Logistic project just by adding react-window to a waybill list. Page load time dropped from 15 seconds to 0.5 seconds. The boss thought I'd performed some incredibly complex magic, but in reality, I just "tricked" the browser with this "optical illusion."

And remember one thing: Virtualization comes with a price in Accessibility and Search (Ctrl + F). Since rows don't actually exist, the browser cannot find them. You have to build your own search mechanism.

The biggest lesson: Never force the browser to do useless work. Don't draw things the user doesn't see. Be calculatedly lazy—that is the peak of performance.


Notes for my 22-year-old self, when I started learning to 'trick' the browser artistically.

Series • Part 15 of 50

50 FRONTEND LESSONS – HARD-EARNED EXPERIENCES

NextBlog #16: Misplaced Debounce – When a localized solution becomes a system burden
Blog #14: The Domino Effect – When one small change crashes the whole Render system
10Blog #10: Specificity War – When !important marks the start of a civil war11Blog #11: Don't wait until 'heavy web' to lose weight for your Bundle12Blog #12: Don't bring the whole supermarket home just to buy a loaf of bread13Blog #13: When optimization becomes a burden – Don't 'memo' everything you see14Blog #14: The Domino Effect – When one small change crashes the whole Render system15Blog #15: The 10,000-Row Lesson – When Table Virtualization saved my careerReading16Blog #16: Misplaced Debounce – When a localized solution becomes a system burden17Blog #17: Images vs JS – The battle for priority in the Critical Path18Blog #18: Laggy Animations – When the touch is no longer smooth19Blog #19: Chrome Performance Tab – Looking through a microscope at the system's pulse20Blog #20: The Mystery of LCP – Why do 'fast' websites still get rated low?
TP

Written by Truong Pham

Software Engineer passionate about building high-performance systems and meaningful experiences.

Read more articles