Skip to main content

Benchmark methodology

The repository benchmark is a head-to-head of React markdown renderers doing the thing that matters while a model is talking: taking one more chunk and getting it on screen.

Each renderer × fixture is split into fixed-size chunks and fed one at a time. A frame times both the write and the React commit:

const t0 = performance.now();
stream.write(chunk);
flushSync(() => root.render(stream.element()));
frames.push(performance.now() - t0);

For renderers that accumulate a string and parse in the component, the work is in render. For HyperMarkdown, write() is the parse. Timing only one of them flatters one design.

Measurements run in their own process under NODE_ENV=production. The report uses the run with the median total time.

Fixtures

FixtureWhat it stresses
code-large.mdOne growing fenced block — block-level freezing cannot help
table-large.mdSame, plus inline markup in every cell
prose-mixed.mdMany small blocks, where block-level freezing does help
real-code-os.mdCaptured model output, 8-character frames
real-table-head.mdCaptured model table, 8-character frames

The captured fixtures are not generated stress cases. Their content is real AI output.

How to read the table

Absolute milliseconds are from one machine on one day (Apple M2 Max in the published run). Ratios travel; milliseconds do not.

Read the DOM-nodes and rendered-percent columns before the times. A renderer that defers or skeletons a block is doing less work.

Reproduce locally:

npm install
npm run benchmark

Full notes live in benchmarks/README.md and benchmarks/results/latest.md.