Skip to content

perf(chat): bound Pierre file-pair rendering - #8328

Open
Pearcekieser wants to merge 1 commit into
kirodotdev:mainfrom
Pearcekieser:perf/pierre-file-pair-budget
Open

perf(chat): bound Pierre file-pair rendering#8328
Pearcekieser wants to merge 1 commit into
kirodotdev:mainfrom
Pearcekieser:perf/pierre-file-pair-budget

Conversation

@Pearcekieser

@Pearcekieser Pearcekieser commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Problem / Motivation

Large raw old/new file pairs can block the dashboard renderer before Pierre's worker pool or row virtualizer can help. A captured client trace showed three Pierre/Shiki main-thread tasks lasting 4.40 seconds, 2.49 seconds, and 2.41 seconds while entering Chat, switching sessions, and rendering paginated history.

Pierre 1.3.5 constructs file-pair metadata synchronously through MultiFileDiff -> parseDiffFromFile -> createTwoFilesPatch -> processFile. Worker-backed highlighting does not bound that initial work.

Why it matters

The measured tasks accounted for 90.2% of long-task time, produced a 4.55-second visible freeze, and delayed one interaction by 2,545 ms. Code-heavy chats become unresponsive during navigation even when the destination response has not arrived yet.

What changed (motivation → approach → change)

The public PierreFilePair wrapper now owns a layout-independent input budget before its lazy Pierre chunk loads.

  • Pairs within 400 lines per side and 131,072 combined UTF-16 code units keep the existing Pierre renderer.
  • Larger pairs bypass Pierre and show both complete files in a themed plain view.
  • The fallback preserves header slots, collapsed rows, selection, wrapping, split and unified layouts, narrow stacking, and the existing 376 px chat-row scroller.
  • Scrollable source regions are keyboard reachable.
  • A translated Large file — simplified view status explains why highlighting and line-level diff controls are absent.
  • Oversized live-edit buffers remain editable through the normal file editor without live diff decoration.
  • Source-only rendering and already-computed unified patches are unchanged.

Relationship to #7916

PR #7916 overlaps FileChangeChips, PlainCodeFallback, and the Pierre wrapper as part of a broader history-pagination, staged-rendering, and phone-scroll rewrite.

This PR is intentionally based directly on main, not on #7916. The two changes address different costs. #7916 changes when transcript and diff work becomes reachable; this PR places a measured hard bound on synchronous raw file-pair construction whenever a pair is rendered. Expanded rows, side panels, and live-diff editing still need that bound after staged mounting or history pagination lands.

Shipping the guard directly keeps a separate regression and rollback boundary for the measured freeze. Waiting for or stacking on #7916 would couple a focused renderer safety limit to a much larger in-flight history rewrite and duplicate its review dependencies. Any textual conflict can be resolved when main moves without changing this PR's policy or tests.

Tests

  • pierre.renderBudget.test.ts pins exact line and UTF-16 code-unit boundaries, uneven pairs, and new-file behavior.
  • PierreFilePair.budget.test.tsx proves oversized pairs never mount Pierre while preserving both files, header defaults, collapsed controls, keyboard regions, separators, and caller sizing.
  • PierreEditorImpl.test.tsx proves oversized live diffs remain editable.
  • FileChangeChips.headerSlots.test.tsx pins the shared 376 px fallback scroller.
  • Fresh-worktree focused run: 60 tests passed across 4 files.
  • TypeScript, ESLint, full i18n checks, and the production build passed.
  • Two independent pre-publication reviews found six fallback parity and accessibility issues; all were fixed and reverified.

Manual verification

A real Chromium fixture rendered a synthetic 401-line pair and verified:

  1. The simplified view appears instead of Pierre rows.
  2. Both complete sides remain selectable.
  3. The content stays inside the 376 px internal scroller.
  4. Two keyboard-focusable source regions are present.
  5. Desktop uses side-by-side panes and narrow width stacks them.
  6. No page errors occur.

Screenshots / video

Desktop split view

Large file pair in the bounded desktop fallback

Narrow stacked view

Large file pair in the bounded narrow fallback

Related Issues

Fixes #8241

Possible overlap: #7916, as described above.

Pattern harvest

Rule candidate: review-prompt
Pattern: Worker offload does not bound synchronous preprocessing that runs before the worker request; expensive renderers need an app-owned input budget at their public boundary.

Checklist

  • At most two commits (one is the norm), with a Conventional Commits title (feat|fix|docs|refactor|perf|test|chore|ci|build|revert: ...)
  • Existing tests pass and new tests added for new functionality
  • Self-review completed; code follows project style guidelines
  • Documentation updated (if applicable)
  • No secrets, credentials, or internal references in the diff

@Pearcekieser
Pearcekieser requested a review from a team September 4, 2026 00:00
@Pearcekieser
Pearcekieser requested a review from a team as a code owner September 4, 2026 00:00
@github-actions github-actions Bot added fork Pull request from a fork (external contributor) readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Sep 4, 2026
@Pearcekieser
Pearcekieser force-pushed the perf/pierre-file-pair-budget branch from 0fe7484 to 9fd5ea9 Compare September 4, 2026 01:10
Bypass synchronous Pierre diff construction for oversized old/new source pairs while preserving complete content, editing, header controls, and responsive chat-row scrolling.
@Pearcekieser
Pearcekieser force-pushed the perf/pierre-file-pair-budget branch from 9fd5ea9 to 5cbc0f6 Compare September 4, 2026 02:22
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fork Pull request from a fork (external contributor) readiness: action required A blocking check or review needs attention

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Large file-pair diffs can freeze the chat renderer

1 participant