perf: debounce IndexedDB save off the render hot path (≈200× faster updates)#13
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
saveState()ran synchronously on everyupdateCanvas(), 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: eachupdateCanvas≈ 80 ms, so the app felt sluggish everywhere.Fix (no quality loss)
scheduleSaveState(): a 700 ms trailing debounce used byupdateCanvasandaddLocalizedImage, with an immediate flush onbeforeunload/visibilitychangeso nothing is ever lost. The immediatesaveState()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)
No console errors. Verified in the preview.
🤖 Generated with Claude Code