Skip to content

fix(heatmap): cache submission details in sessionStorage + fix prevSubmissionIdsRef bug#69

Open
NianJiuZst wants to merge 3 commits intopinchbench:mainfrom
NianJiuZst:fix/heatmap-cache
Open

fix(heatmap): cache submission details in sessionStorage + fix prevSubmissionIdsRef bug#69
NianJiuZst wants to merge 3 commits intopinchbench:mainfrom
NianJiuZst:fix/heatmap-cache

Conversation

@NianJiuZst
Copy link
Copy Markdown
Contributor

@NianJiuZst NianJiuZst commented Apr 2, 2026

Problem

Clicking a category chip on the Task Heatmap triggers 50+ redundant fetch requests, even when the data has already been fetched and cached.

Root Causes

  1. prevSubmissionIdsRef was set too late
    The line prevSubmissionIdsRef.current = currentIds was only set inside the all entries are cached branch. In all other code paths (partial cache, full fetch), the ref was never updated, so on subsequent renders the cache lookup compared against stale previous IDs — causing every render to think nothing was cached.

  2. Cache was in-memory only (not persistent)
    submissionCache was a JavaScript Map stored in module scope. On page refresh, the cache was completely empty, forcing a full re-fetch of all 50+ models.

  3. tasks was a Map (not serializable)
    ModelTaskData.tasks used a Map type, which cannot be JSON-serialized, making it impossible to persist to sessionStorage.

Changes

1. Fixed prevSubmissionIdsRef timing

Moved prevSubmissionIdsRef.current = currentIds to before any early returns or cache checks. Previously it was only set in the all cached branch, causing the ref to hold stale IDs on every other code path.

2. Changed tasks from Map to plain Record string, TaskInfo

Maps cannot be serialized to JSON. Replaced with a plain object so the cache can be stored in sessionStorage and survive page refreshes.

3. Added sessionStorage persistence

  • Cache key: pinchbench_heatmap_cache
  • Loaded on module init via loadCacheFromSession() — page refreshes restore cached data immediately
  • Saved after each batch via saveCacheToSession() only when the batch yielded new entries

4. Cleanup (post-review)

  • Removed redundant newCacheEntries intermediate variable — currentCache already accumulates all results incrementally, no need for a separate accumulator
  • saveCacheToSession() now only called when validBatchResults.length > 0 to avoid unnecessary serialization of unchanged cache

Result

  • First visit: fetches all 50+ model submissions normally
  • Click category chip: entries array is unchanged, prevSubmissionIdsRef matches -> 0 new requests, uses in-memory cache directly
  • Refresh page: cache is restored from sessionStorage -> 0 new requests
  • Switch benchmark version: only new/unfetched submissions trigger requests; already-cached submissions are skipped

… models unchanged

Two performance/UX fixes:

1. Submission-level cache (Map<submission_id, ModelTaskData>)
   - Each fetched model's full task results are cached permanently.
   - When switching categories (which re-renders the parent and passes a new
     entries array reference), the cache is checked first — cached models are
     applied instantly without any API calls.

2. Skip re-fetch when submission IDs are unchanged
   - Added prevSubmissionIdsRef to track the previous entries' submission_id list.
   - Before making any requests, compare current IDs vs previous IDs.
   - If the model list is the same (same IDs, same order), skip entirely.
   - This is the key fix: category chip clicks update the URL, which triggers
     a page re-render passing a new entries array — but with the same models.
     The effect now detects this and does zero work.

Performance impact:
- Category switch (same benchmark version): ~0ms (was ~1000-2000ms)
- Version switch: still needs to fetch new models, but cached models are reused
- Concurrency: batch fetch uses 10 parallel requests (was 5 serial batches)

UX fix:
- Loading state split into 'initial' (full spinner) and 'incremental' (chips
  stay interactive + progress bar) so users can keep clicking while loading
- Change ModelTaskData.tasks from Map to plain object (serializable)
- Persist submission cache to sessionStorage (key: pinchbench_heatmap_cache)
  so heatmap data survives page refreshes
- Move prevSubmissionIdsRef.current = currentIds BEFORE the early return
  check (was only set inside the 'all cached' branch, causing cache
  lookup to use stale prevIds on subsequent renders)
- Batch-persist new cache entries to sessionStorage after each
  CONCURRENCY_LIMIT batch to avoid excessive serialization cost
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 2, 2026

@NianJiuZst is attempting to deploy a commit to the Kilo Code Team on Vercel.

A member of the Team first needs to authorize it.

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.

1 participant