Priority: P3 · Review finding: #20
static/js/detail.js _detailNext/_detailPrev use navigateReplace, which re-runs showDetail → _loadDetail → apiGet(/api/scans/:id?page=0&size=10000). Every arrow-key press re-downloads and re-parses the full scan (potentially MBs on large scans).
Fix: cache _detailFailures keyed by scanId and skip the refetch when only the filename changed (refresh on scan change or via the watch poll).
Priority: P3 · Review finding: #20
static/js/detail.js_detailNext/_detailPrevusenavigateReplace, which re-runsshowDetail→_loadDetail→apiGet(/api/scans/:id?page=0&size=10000). Every arrow-key press re-downloads and re-parses the full scan (potentially MBs on large scans).Fix: cache
_detailFailureskeyed by scanId and skip the refetch when only the filename changed (refresh on scan change or via the watch poll).