Part VI β The Blueprint Β· Lesson 11.12
HLD β Google Sheets
In one lineA virtualized grid over a dependency graph β render what's visible, recalculate only what changed.
Where you've seen itTyping a number into A1 and having exactly the cells that reference it update, instantly, in a sheet with a million rows.
Diagram
1β2 Β· SCOPE AND SCALE
in scope grid Β· editing Β· formulas Β· scroll Β· selection Β· collab
out charts Β· pivot tables Β· apps script Β· import/export
scale up to 10M cells Β· 1M rows Γ 26 cols visible-addressable
only ~1,000 cells on screen at any moment3 Β· VIRTUALIZED GRID β two dimensions, not one
ββββ frozen header row βββββββββββββββββββββββββ
β β C β D β E β F β β
βββββΌββββββΌββββββΌββββββΌββββββ€ β
β 8 β β β β β ~40 rows Γ β
β 9 β β β β β β ~25 cols β
β10 β β β β β = 1,000 cells β
β11 β β β β β RENDERED β
βββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ β
β² β
frozen column β
β
scrollTop β startRow = floor(scrollTop / rowHeight)
scrollLeft β startCol (prefix-sum if widths vary)
spacers hold total scrollable size (10.7)
Never mount 10M cells. Mount ~1,000 and translate the window.6a Β· DEEP DIVE β THE DEPENDENCY DAG
A1 = 10
B1 = A1 * 2 B1 depends on A1
C1 = B1 + A1 C1 depends on B1, A1
D1 = SUM(A1:C1) D1 depends on A1, B1, C1
A1 βββΊ B1 βββΊ C1 βββΊ D1
ββββββββ΄βββββββ΄βββββββ
edit A1
β find dependents (reverse edges)
β topological sort β recalc in order: B1, C1, D1
β recalc ONLY those cells, never the whole sheet
cycle detection: A1 = B1 and B1 = A1 β #CIRCULAR!, don't hang6b Β· DEEP DIVE β KEEPING EDITS AT 60fps
parse formula once β AST, cached per cell
recalc in a Web Worker when the dirty set is large (5.1)
batch renders: one paint per frame, not per recalculated cell
canvas rendering for the grid body if DOM cells prove too slow
virtualize selection: a 10,000-cell range is a rectangle,
not 10,000 selected elementsHow it works
- Sparse storage: a map keyed by
"R3C7", so empty cells cost nothing. - Virtualize both axes, with frozen headers rendered as separate panes.
- Build a dependency graph as formulas are parsed; edits walk reverse edges and recalculate topologically.
- Detect cycles at parse time and report
#CIRCULAR!rather than hanging. - Collaborate per cell β unlike prose (11.11), cells are independent, so per-cell last-write-wins is usually acceptable.
Trade-offs
| Choice | Cost |
|---|---|
| DOM cells | Easy styling and a11y; slower past a few thousand |
| Canvas grid | Fast at any size; you rebuild a11y and editing |
| Full recalc | Trivial to write; unusable at scale |
| DAG recalc | Fast and correct; graph maintenance complexity |
Interview angle
"How do you recalculate a sheet with 10 million cells?"
- You don't recalculate the sheet β you recalculate the dependents of the edited cell, found via reverse edges in a DAG and ordered topologically.
- Detect cycles at parse time so a circular reference errors instead of hanging the tab.
- If the dirty set is large, run recalculation in a Web Worker and batch one repaint per frame so typing stays responsive.
Recap
- Virtualize both axes; only ~1,000 cells ever exist in the DOM.
- The dependency DAG is what makes editing fast β recalc the dependents, not the sheet.
- Cells are independent, so collaboration is far simpler here than in a document.