Skip to content

Bound unbounded renderer caches (URL previews, wiki hover, clipboard blob) #448

Description

@h4yfans

Summary

Several renderer-side caches grow without an upper bound across a session. Individually small, together they leak steadily and pin DOM/Blob references.

Evidence

  • apps/desktop/src/renderer/src/lib/url-metadata.ts:18 — module-level cache: Map<string, Promise<UrlMetadata>> for link previews. No eviction. Grows with every distinct URL rendered.
  • apps/desktop/src/renderer/src/hooks/use-wiki-link-hover.ts:36 — per-hook-instance Map capped at 50 entries, but multiple instances exist concurrently across mounted editors. Each preview holds a snippet of note content.
  • apps/desktop/src/renderer/src/components/quick-capture.tsx:160,199,205 — pasted clipboard Blob retained in component state plus its ObjectURL. URL is revoked on unmount, but the Blob itself can stay pinned across multiple captures in the same quick-capture window session.

Proposed Work

  • URL preview cache: convert to LRU, cap 200 entries, expose a dev-tooling clear method.
  • Wiki hover cache: hoist into a single shared module-level LRU keyed by note id, cap 100, drop per-hook caches.
  • Quick capture: revoke ObjectURL and null the Blob reference immediately after the capture is committed or discarded. Don't carry the prior blob across paste events.

Acceptance Criteria

  • Each cache documents its cap and eviction policy in a code comment.
  • Unit test: after 1000 distinct URL previews are rendered, the cache has at most 200 entries.
  • Unit test: after committing 20 large screenshot pastes in quick capture, no Blob references remain in component state.
  • No regressions in link preview rendering or wiki hover UX.

Benchmark (worktree vs main)

Depends on the memory snapshot harness landing first.

  1. pnpm memory:snapshot --scenario paste-50-large-screenshots on main.
  2. Repeat on worktree.
  3. Expected delta: renderer usedJSHeapSize at T2 reduced by ≥ 10 MB after the screenshot scenario.

Attach both JSON files plus the compare output to the PR.

Tags: desktop, renderer, caches, blob, memory-footprint

Metadata

Metadata

Assignees

No one assigned

    Labels

    complexity-lowLow complexityenhancementNew feature or requestmemory-footprintReduce desktop app memory footprint and main-process resident set

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Inbox

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions