Skip to content

Profile and reduce first-open multibuffer diff excerpt-construction stalls #155

Description

@kjanat

Report

Large diffs are slow on their first view/load in the multibuffer diff viewer. Investigate and reduce foreground work during excerpt construction, particularly for files containing many hunks and in split view.

This is a profiling-led investigation: the relevant synchronous work is confirmed in source, but no UI trace or reproducibly slow user fixture has yet established it as the dominant bottleneck. The user's unified/split mode and whether the delay is a loading view or a UI freeze are not yet known.

Source evidence

At 5ee612d:

  • register_buffer collects all hunk ranges for a loaded file and updates excerpts synchronously through the UI context.
  • update_excerpts_for_path builds, sorts, merges, and installs excerpt ranges.
  • Split view additionally runs sync_lhs_for_paths, mapping the right-side excerpts to base-text ranges and updating the left-side multibuffer.
  • The loader yields between files, but does not break one file's register_buffer call into smaller foreground slices.

Do not conflate this with rendering every line: ordinary text layout is limited to visible rows, with an additional longest-row measurement for horizontal scrolling. Diff computation also already runs on a background executor, although file presentation waits for its result. Horizontal virtualization alone would not eliminate the loading and excerpt-construction work described here.

Investigation and acceptance criteria

  • Capture time to first useful content and maximum foreground stall for many small files, one large file with many hunks, and a few extremely long lines.
  • Compare cold/warm opening and unified/split view.
  • Separate Git reads, buffer creation, diff computation, excerpt insertion, left-side synchronization, and first layout in the measurements.
  • If foreground construction dominates, move suitable preparation off-thread or install results in bounded batches, preserving editing, hunk staging, selection, and scroll behavior.
  • Add a representative regression benchmark for the measured bottleneck and report before/after timings. Avoid claiming a rendering fix based only on Git-read timings.

Upstream research (2026-09-29)

  • Strongest matching evidence: open issue #55392, particularly its trace-analysis comment. That analysis reports five main-thread spans over 90 seconds and attributes the stalls to per-buffer excerpt registration; diff computation reportedly peaked at 327 ms. A later process sample points to ProjectDiff::refresh -> register_buffer -> MultiBuffer::add_diff -> sync_diff_transforms. These are upstream-reported historical measurements, not an independently reproduced profile of our current fork. Include add_diff and sync_diff_transforms in the investigation.
  • Issue #52004 reports 16–32 second main-thread stalls with buffer/project-diff traces. It was closed for inactivity; the thread does not establish a fix.
  • Issue #40186 includes a supplied large-file reproduction that a maintainer confirmed. It was closed as a duplicate of #40908, which was subsequently closed for inactivity and has a later report involving large JSON/YAML diffs. Neither closure proves the original text-file freeze was fixed.
  • Issue #44734 includes a hang-trace attachment and reports hangs with large diffs/search multibuffers. It was closed as a duplicate of the broader search issue Poor search performance in large repositories zed-industries/zed#38799. The reporter explicitly distinguished full UI freezes from slow search results.
  • Open PR #55813 avoids traversing diff hunks inside folded buffers. Its motivating case is a collapsed, heavily modified lockfile causing severe lag while visible. This addresses a different but relevant phase: rendering after folding.
  • Open PR #63499 adds bulk merge-conflict block insertion. Its author reports foreground insertion falling from 5.91 s to 1.77 s and total refresh from 11.50 s to 7.31 s on a synthetic conflict-heavy workload. These are contributor measurements for merge-conflict blocks, not ordinary diff excerpts or our own validation.
  • Merged PR #63395 limits row-highlight expansion to the viewport. Account for that existing optimization when reproducing historical reports rather than assuming their exact hot paths remain unchanged.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions