Performance
Zoijs is fast because of what it doesn't do: there's no Virtual DOM to diff, components run once, and an update touches only the exact node that changed. The numbers below are reproducible — run npm run bench in the repo.
Size#
No build step means the published package is its source, so the gzipped size is exactly what a browser fetches from a gzip/brotli CDN.
| Size (gzipped) | |
|---|---|
| @zoijs/core | ~13 KB |
| React + ReactDOM | ~45 KB |
A 16 KB budget fails CI if the core ever grows unexpectedly.
Cost scales with what changed#
DOM micro-benchmarks on a 1,000-row table (jsdom — read the shape, not the absolute milliseconds):
| Operation | Time |
|---|---|
| Create 1,000 rows | ~70 ms |
| Update all 1,000 | ~5 ms |
| Update 1 of 1,000 | ~0.4 ms |
| Swap 2 rows | ~0.5 ms |
| Reverse 1,000 rows | ~31 ms |
| Clear 1,000 rows | ~17 ms |
Updating one row of a thousand is ~12× cheaper than updating all, and ~160× cheaper than creating them. There is no whole-list diff — only the changed text node updates.
Minimal DOM moves#
Reordering a keyed list moves the fewest nodes possible — a longest-increasing-subsequence pass means moving one item across a list is one DOM move, not many. Reused nodes keep their identity, so focus, input values, and scroll position survive a reorder.
Reproduce it#
git clone https://github.com/Zoijs/zoijs && cd zoijs
npm run install:all
npm run benchThe deterministic gates — the gzipped-size budget and the each() move-count tests — run in CI on every change, so these numbers can't quietly regress.