1,108 browser samples

Why the page is split into blocks.

The runs compare full-document editors with the widget-first model, including a mixed CMS page and its read-only renderer. Each result keeps its test shape and feature-parity limits beside the number.

Build 04 · 26 August 2026

Composed prose sections

Paragraphs now compose into section-sized editors. DOM and heap dropped sharply, and the benchmark finally separated input cost from persistence delay.
2,017idle elements at 2,000 paragraphs
Section-sized prose100 paragraphs · warm cache · native CPU
MetricFull TiptapLexicalWidget-first
Ready52.3 ms36.8 ms44.7 ms
Input completion43.4 ms10.3 ms45.6 ms
Paste input2.1 ms1.1 ms2.4 ms
Idle heap3.18 MiB2.36 MiB1.69 MiB

Widget JSON commits after a 120 ms idle delay. The editable DOM does not wait for that commit.

Production JavaScript

Full Tiptap242 KiB initial
241.6 KiB total
Lexical133.4 KiB initial
133 KiB total
Widget-first66.9 KiB initial
166.3 KiB total

What changed

Use semantic prose sections. Do not create one widget per paragraph or one editor per book.

  1. Consecutive prose moved inside one multi-paragraph Lexical widget.
  2. Lexical EditorState stayed local during typing.
  3. Input completion and portable-JSON acknowledgement became separate metrics.

A 2,000-paragraph section is intentionally shown as a failed extreme. Production prose should split at real section boundaries.

2026-08-26T15-38-13.856ReportSummaryRaw2026-08-26T15-44-52.026ReportSummaryRaw

Edit one block. Render the rest as content.

This 48-sample run used rich-text sections, callouts, metrics, and three-item galleries at 50 and 200 blocks. It compared the editor withWidgetDocumentView, not another rich-text engine.

All warm cases recorded zero dropped frames and zero long tasks. The galleries used local placeholders, so the run excludes image decoding, embeds, network latency, and application persistence.

Analysis· Summary· Raw data

200 blocks · native1.2 msselection sweep CPU
200 blocks · native38.7 mstype 20 characters
Read-only initial64.7 KiBgzip JavaScript
Read-only · 200 blocks2.16 MiBidle heap