Skip to content

perf: debounce IndexedDB save off the render hot path (≈200× faster updates)#13

Merged
flocom merged 1 commit into
mainfrom
perf/debounce-save
Jun 7, 2026
Merged

perf: debounce IndexedDB save off the render hot path (≈200× faster updates)#13
flocom merged 1 commit into
mainfrom
perf/debounce-save

Conversation

@flocom

@flocom flocom commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Problem

saveState() ran synchronously on every updateCanvas(), structured-cloning the whole project — which for a real multi-language project is ~155 MB of localized image data — into IndexedDB on every keystroke/slider tick. Measured: each updateCanvas80 ms, so the app felt sluggish everywhere.

Fix (no quality loss)

scheduleSaveState(): a 700 ms trailing debounce used by updateCanvas and addLocalizedImage, with an immediate flush on beforeunload / visibilitychange so nothing is ever lost. The immediate saveState() is unchanged for structural changes and cancels any pending debounce. Exactly the same data is saved — just not 155 MB per frame.

Measured (155 MB project, in-browser)

before after
80 ms 0.4 ms
60-render slider drag ~4800 ms 3.4 ms
disk writes during a drag 60 0 (1 after settle)

No console errors. Verified in the preview.

🤖 Generated with Claude Code

saveState() was called synchronously on every updateCanvas() — structured-
cloning the entire project (which can be 100+ MB of localized image data) into
IndexedDB on every keystroke/slider tick. With a real multi-language project
(~155 MB) each render cost ~80 ms, making the whole app sluggish.

Add scheduleSaveState(): a trailing debounce (700 ms) used by updateCanvas and
addLocalizedImage, with an immediate flush on beforeunload / visibilitychange so
nothing is lost. saveState() (immediate) is unchanged and still used for
structural changes; it cancels any pending debounce.

Result (155 MB project, measured): updateCanvas 80 ms → 0.4 ms; a 60-render
slider drag 4800 ms → 3.4 ms with 0 disk writes during the drag (one write after
editing settles). No change to what gets saved — full quality retained.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@flocom
flocom merged commit 7bf2f39 into main Jun 7, 2026
@flocom
flocom deleted the perf/debounce-save branch June 7, 2026 14:33
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