Skip to content

Commit 6b8cfbc

Browse files
committed
perf: plug three HIGH-impact leaks in preview pipeline
- runtime overlay: make 200ms reattach interval stoppable via window.__cs_reattach_interval, clear on pagehide/beforeunload so iframe teardown actually stops the poll loop - hub DesignCardPreview: bound the module-level memCache to 40 entries with insertion-order LRU, matching the existing localStorage cap - renderer store: clear autoPolishFired[designId] in softDeleteDesign so deleted designs don't accumulate in the dedupe set Identified by audit pass; runtime tests 15/15 green, desktop typecheck clean.
1 parent 4c92756 commit 6b8cfbc

3 files changed

Lines changed: 43 additions & 4 deletions

File tree

apps/desktop/src/renderer/src/store.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,6 +1679,9 @@ export const useCodesignStore = create<CodesignState>((set, get) => ({
16791679
}
16801680
try {
16811681
await window.codesign.snapshots.softDeleteDesign(id);
1682+
const nextFired = new Set(get().autoPolishFired);
1683+
nextFired.delete(id);
1684+
set({ autoPolishFired: nextFired });
16821685
const wasCurrent = get().currentDesignId === id;
16831686
await get().loadDesigns();
16841687
if (wasCurrent) {

apps/desktop/src/renderer/src/views/hub/DesignCardPreview.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,26 +50,43 @@ const memCache = new Map<string, string>();
5050
const LS_PREFIX = 'designCardPreview:';
5151
const LS_MAX_CHARS = 300_000; // ~ 300 KB per entry ceiling; skip caching huge HTML
5252
const LS_MAX_ENTRIES = 40;
53+
const MEM_MAX_ENTRIES = 40;
5354

5455
function cacheKey(id: string, updatedAt: string): string {
5556
return `${id}:${updatedAt}`;
5657
}
5758

59+
// Map iteration order = insertion order, so delete+set on hit refreshes recency
60+
// and evicting the first key drops the least-recently-used entry.
61+
function memCacheTouch(key: string, value: string): void {
62+
memCache.delete(key);
63+
memCache.set(key, value);
64+
while (memCache.size > MEM_MAX_ENTRIES) {
65+
const oldest = memCache.keys().next().value;
66+
if (oldest === undefined) break;
67+
memCache.delete(oldest);
68+
}
69+
}
70+
5871
function readCache(key: string): string | null {
5972
const hit = memCache.get(key);
60-
if (hit !== undefined) return hit;
73+
if (hit !== undefined) {
74+
memCache.delete(key);
75+
memCache.set(key, hit);
76+
return hit;
77+
}
6178
if (typeof localStorage === 'undefined') return null;
6279
try {
6380
const raw = localStorage.getItem(LS_PREFIX + key);
64-
if (raw !== null) memCache.set(key, raw);
81+
if (raw !== null) memCacheTouch(key, raw);
6582
return raw;
6683
} catch {
6784
return null;
6885
}
6986
}
7087

7188
function writeCache(key: string, html: string): void {
72-
memCache.set(key, html);
89+
memCacheTouch(key, html);
7390
if (typeof localStorage === 'undefined') return;
7491
if (html.length > LS_MAX_CHARS) return;
7592
try {

packages/runtime/src/overlay.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,26 @@ export const OVERLAY_SCRIPT = `(function() {
207207
}
208208
}
209209
reattach();
210-
try { setInterval(reattach, 200); } catch (err) { console.warn('[overlay] setInterval reattach failed:', err); }
210+
try {
211+
if (window.__cs_reattach_interval) {
212+
try { clearInterval(window.__cs_reattach_interval); } catch (_) {}
213+
window.__cs_reattach_interval = 0;
214+
}
215+
window.__cs_reattach_interval = setInterval(reattach, 200);
216+
if (!window.__cs_reattach_unload) {
217+
window.__cs_reattach_unload = true;
218+
var stopReattach = function() {
219+
try {
220+
if (window.__cs_reattach_interval) {
221+
clearInterval(window.__cs_reattach_interval);
222+
window.__cs_reattach_interval = 0;
223+
}
224+
} catch (_) {}
225+
};
226+
try { window.addEventListener('pagehide', stopReattach, false); } catch (_) {}
227+
try { window.addEventListener('beforeunload', stopReattach, false); } catch (_) {}
228+
}
229+
} catch (err) { try { console.warn('[overlay] setInterval reattach failed:', err); } catch (_) {} }
211230
212231
// Neutralize programmatic navigation — generated code may call
213232
// window.location = '/foo', location.assign('/x'), or window.open(...)

0 commit comments

Comments
 (0)