perf(core): incremental drawlist emission#29
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 99dba499e1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const ap = a.props as { style?: unknown; textOverflow?: unknown; variant?: unknown; maxWidth?: unknown }; | ||
| const bp = b.props as { style?: unknown; textOverflow?: unknown; variant?: unknown; maxWidth?: unknown }; | ||
| if (ap.textOverflow !== bp.textOverflow) return false; | ||
| if (ap.variant !== bp.variant) return false; | ||
| if (ap.maxWidth !== bp.maxWidth) return false; |
There was a problem hiding this comment.
Compare text ids before fast-reusing leaf nodes
This equality check treats two text vnodes as equivalent even when their id differs, so commitNode reuses the previous RuntimeInstance and keeps the old vnode.props.id. That makes id-based lookups (for example, rect indexing in buildLayoutRectIndexes and any anchorId references) continue pointing at the stale id when only the id changes but text/style stays the same. This regression appears whenever apps dynamically retag text nodes without changing their rendered content.
Useful? React with 👍 / 👎.
| if (prev && prev.vnode.kind === vnode.kind && leafVNodeEqual(prev.vnode, vnode)) { | ||
| return { ok: true, value: { root: prev } }; |
There was a problem hiding this comment.
Keep lifecycle reuse tracking on leaf fast path
The leaf fast-return exits before lifecycle bookkeeping, so unchanged leaf nodes are no longer appended to reusedInstanceIds even when collectLifecycleInstanceIds is left at its default (true). Any caller that relies on commitVNodeTree(...).reusedInstanceIds to represent all reused nodes in a commit now gets incomplete data for text/spacer/divider subtrees.
Useful? React with 👍 / 👎.
99dba49 to
a021d3d
Compare
Key optimizations across commit, reconciliation, and render phases: - commit.ts: Add leaf VNode equality fast path to reuse RuntimeInstance for unchanged text/spacer/divider nodes. Add container subtree reuse when all children return identical references. Use shared EMPTY_CHILDREN constant for leaf nodes. Remove Object.freeze+slice from commitVNodeTree. - reconcile.ts: Pre-allocate arrays in reconcileUnkeyedChildren with known sizes, use indexed assignment instead of push. Add EMPTY_INSTANCE_IDS shared constant. - spacing.ts: Return shared ZERO_SPACING constant for the common no-padding case, avoiding per-node object allocation. - containers.ts: Skip childClip allocation and extra clip operations when spacing is zero. Avoid mergeTextStyle call when no style override. - basic.ts: Add ASCII fast path for text nodes to skip measureTextCells when text fits within rect. Add early-exit for unstyled text nodes. Results (content-update, 500-row list): Before: 3.25ms → After: 1.86ms (-43%) Now beats terminal-kit (1.98ms) and 2.7x of blessed (679µs) Results (rerender, 10-item list): Rezi: 30µs — fastest across all frameworks blessed: 57µs, terminal-kit: 64µs All 873 tests pass with zero regressions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add damage-based rendering in WidgetRenderer for render-only updates and content-update bench. Includes identity-diff damage tracking, damage-rect culling, and regression tests.
a021d3d to
ce56631
Compare
Implements internal damage-based incremental rendering in WidgetRenderer (no public API changes).
Bench: content-update improved to ~1.1ms on this machine (still behind blessed ~0.7ms).