Skip to content

perf(workstation): debounce + cache commit file-preview hydration#1571

Open
gfargo-horizon-agent[bot] wants to merge 1 commit into
mainfrom
agent/coco-595-debounce-hash-keyed-cache-for-commit-det
Open

perf(workstation): debounce + cache commit file-preview hydration#1571
gfargo-horizon-agent[bot] wants to merge 1 commit into
mainfrom
agent/coco-595-debounce-hash-keyed-cache-for-commit-det

Conversation

@gfargo-horizon-agent

@gfargo-horizon-agent gfargo-horizon-agent Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

What

Adds a ~120ms debounce and a bounded (hash, path, oldPath)-keyed cache to useCommitFilePreviewHydration, so holding j/k over a commit's file list stops firing an uncached git show subprocess per cursor move and previously-visited previews redisplay instantly with no loading flash.

Why

Plane: OSS-595

Sub-item 2/5 of OSS-338. Its sibling hook, useCommitDetailHydration, already got this treatment in #1533. This closes the remaining gap: useCommitFilePreviewHydration (in useDiffHydration.ts) was still fetching uncached on every selectedDetailFile change.

How

  • useCommitFilePreviewHydration: added a useRef-backed, size-capped (100 entries, FIFO eviction) cache keyed by ${hash}\0${path}\0${oldPath ?? ''} (oldPath is included because renamed files pass different paths to git show).
  • Debounced the fetch by 120ms; rapid re-selection clears the prior timer via the existing active-flag cleanup, mirroring useCommitDetailHydration.
  • On a cache hit: setFilePreview(cached) + setFilePreviewLoading(false), no fetch, and setFilePreviewLoading(true) is never called.
  • Preserved the active-flag stale-response guard, the safe() wrapper, the no-selection bail, and the dependency array exactly — no change to the exported hook signature or the app.ts call site (only an internal useRef was added).
  • Updated the module and hook doc comments to note this loader is no longer a verbatim lift (the other four diff loaders remain verbatim).
  • No changes were needed to useCommitDetailHydration.ts — that half of the ticket was already merged in perf(workstation): debounce + cache commit detail hydration #1533.

Testing

  • npm run build passes
  • npm run test:jest passes (useDiffHydration.test.ts: 17/17; full jest suite: 4707/4724 passing — the 10 unrelated failing suites were SIGKILL/OOM from running the full suite under constrained sandbox memory, confirmed to pass individually and unrelated to any file touched here)
  • npm run lint clean (0 errors; pre-existing exhaustive-deps warnings only, consistent with sibling hooks in this file)
  • Added fake-timer unit tests: debounce (single fetch after 120ms), rapid re-selection (timer reset, single fetch), cancellation (cleanup before debounce elapses), and cache hit (no fetch, loading never toggles true)
  • CI: pending

🤖 Generated by the harbor agent loop. Reviewed by a human before merge.

Adds the same 120ms debounce + bounded (hash, path, oldPath)-keyed
cache pattern already shipped for useCommitDetailHydration (#1533) to
useCommitFilePreviewHydration, so holding j/k in a commit's file list
no longer fires an uncached git show subprocess per cursor move and
previously-visited previews redisplay instantly.

Co-Authored-By: Claude Sonnet 5 <[email protected]>

@gfargo-horizon-agent gfargo-horizon-agent Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔎 Agent review (sonnet) — LGTM

REVIEW: LGTM
RESOLVES: full

The diff correctly mirrors the already-merged useCommitDetailHydration debounce+cache pattern for the file-preview loader, preserving the active-flag guard, safe() wrapper, and hook-position constraints, with fake-timer tests covering debounce, cancellation, and cache-hit-skips-loading behavior. Scope is tightly limited to the two named files with no touches to app.ts or the sibling hook.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants