← the lab coinupbtc.com

Demo 03

Render cost

In a table UI, selecting one row rebuilt every row — and read layout back from the DOM on each one — so the click got slower as the table grew. Below is that bug and its fix, side by side. Your browser does the timing; the numbers on this page are measured on your machine when you press Run.

512
5
Rebuild everything
— ms

Regenerate all rows, then read layout back per row.

Touch what changed
— ms

Two class changes, one layout read at the end.

Gap
—×

Run it to find out what your machine does.

Live table — click any row 512 rows

What actually went wrong

The handler did the obvious thing: mark the clicked row as selected, then re-render the table so the highlight shows up. Re-rendering meant building every row again. That alone is O(N) work for an O(1) change, which is wasteful but survivable.

The bigger cost was the second mistake: each row's size was read back out of the layout engine immediately after it was written. Writing invalidates layout; reading forces it to be recomputed on the spot. Do both in a loop and the browser recalculates the whole document once per row — a full layout pass per row, for one click.

The fix was not an optimisation. It was deleting work: stop rebuilding rows that did not change, and stop asking for layout inside the loop. The click cost stops depending on row count.

Drag rows up and run it again. The red bar should grow with the row count — roughly quadratically, since the per-row cost also rises as the document gets bigger. The green bar should barely move: it does the same two class changes whether there are 64 rows or 2048.

An honest note on the numbers. The only timings on this page are the ones your browser measures when you press Run; they depend on your machine and engine. What the demo shows is the shape: an O(1) change priced as O(N), amplified by synchronous layout reads, and a fix that is subtraction rather than cleverness.