Skip to content

perf: webview/app §8 measurements + migration-checksum heal#15

Merged
danielss-dev merged 1 commit into
mainfrom
perf/webview-baseline-and-migration-heal
Jun 29, 2026
Merged

perf: webview/app §8 measurements + migration-checksum heal#15
danielss-dev merged 1 commit into
mainfrom
perf/webview-baseline-and-migration-heal

Conversation

@danielss-dev

Copy link
Copy Markdown
Owner

Summary

Two things from one session: the webview/full-app performance pass (the PRD §8 targets the engine harness can't cover), and a migration-checksum data-persistence bug it surfaced and fixes.

Measured against the real production app via WebView2's DevTools Protocol (--remote-debugging-port) + a perf-gated window.__strand store hook. Win 11 / Ryzen 7 7700X, v0.7.0. Full numbers + methodology in docs/perf-baseline.md § "Webview / full-app baseline".

Performance results vs PRD §8

target measured verdict
Cold start < 1.0s ~407ms launch→shell paint, ~568ms launch→repo-interactive ✅ pass
Stage/unstage hunk < 50ms ~34ms isolated ✅ pass
Diff render 5,000-line < 100ms ~87ms normal diff; ~1460ms whole-file in non-virtualized Local Changes; bounded in Review ⚠️ mixed
Idle memory < 250MB ~280MB private / ~438MB WS (JS heap 7MB → WebView2 6-process baseline) ❌ over

Two follow-ups filed in TASKS.md: virtualize the Local Changes stacked diff pane, and reconcile the memory target with WebView2's floor.

ui/src/main.tsx gains a store hook exposed on window.__strand only when localStorage['strand:perf']==='1' (same gate as the perf instrumentation) — lets an external CDP harness drive the app without a native dialog. Zero effect on normal use.

Migration-checksum fix (data-persistence bug)

sqlx stores a SHA-384 checksum of each migration's SQL and refuses to open a DB whose stored checksum no longer matches the binary. Commit 3e1f0bb reindented migration 1's SQL (whitespace only), so every strand.db created before it — including public 0.x installs — failed to open, silently disabling session restore and all SQLite-backed settings persistence (the load error was caught and fell back to defaults).

  • state::repair_migration_checksums recomputes each migration's checksum the way sqlx does and rewrites any stale _sqlx_migrations row, in Tauri setup() before the SQL plugin's migrator runs (the webview's first Database.load).
  • Lossless: every migration is idempotent CREATE … IF NOT EXISTS, so the applied schema is identical regardless of whitespace — nothing re-runs and no user data (recents/icons/review state) is touched.
  • sqlx + sha2 added as direct deps (already in the tree via tauri-plugin-sql).
  • Process rule going forward: migrations are append-only; never edit an applied migration's SQL.

Verification

  • cargo check, cargo clippy -p strand-tauri -- -D warnings, tsc -b (via tauri build).
  • End-to-end CDP run of the perf measurements.
  • Migration heal verified against the real broken DB: v1 checksum healed (5E02…6D23…), v2 then applied, session restore + persistence work, no console error.

🤖 Generated with Claude Code

…on-checksum DB break

Webview/full-app performance pass (the PRD §8 targets the engine harness
can't cover), measured against the real production app via WebView2's
DevTools Protocol (--remote-debugging-port) + a perf-gated window.__strand
store hook. Win 11 / Ryzen 7 7700X, v0.7.0. Full numbers + methodology in
docs/perf-baseline.md § "Webview / full-app baseline".

- Cold start: ~407ms launch->shell paint, ~568ms launch->repo-interactive. PASS (<1.0s)
- Stage/unstage perceived: ~34ms isolated. PASS (<50ms)
- Diff render 5,000-line: ~87ms for a normal hunk-sized change, but ~1460ms for a
  whole-file diff in the non-virtualized Local Changes pane (7,500 line elements);
  the virtualized Review pane caps mounted rows at ~100. MIXED -> follow-up filed
  to virtualize the Local Changes stacked diff pane.
- Idle memory: ~280MB private / ~438MB working set (medium repo); JS heap is 7MB,
  so the overage is WebView2's 6-process baseline (~408MB empty), not app code.
  OVER 250MB target -> needs process-count reduction or a per-platform target.

main.tsx gains a store hook exposed on window.__strand only when
localStorage['strand:perf']==='1' (gated by the same flag as the perf
instrumentation), so an external CDP harness can open repos / select files /
stage without a native dialog. Zero effect on normal use.

Migration-checksum data-persistence fix (surfaced during the pass):
sqlx stores a SHA-384 checksum of each migration's SQL and refuses to open a
DB whose stored checksum no longer matches the binary. Commit 3e1f0bb
reindented migration 1's SQL (whitespace only), so every strand.db created
before it -- including public 0.x installs -- failed to open, silently
disabling session restore AND all SQLite-backed settings persistence (the
load error was caught and fell back to defaults).

- state::repair_migration_checksums recomputes each migration's checksum the
  way sqlx does and rewrites any stale _sqlx_migrations row, in Tauri setup()
  before the SQL plugin's migrator runs (the webview's first Database.load).
- Lossless: every migration is idempotent CREATE ... IF NOT EXISTS, so the
  applied schema is identical regardless of whitespace -- nothing re-runs and
  no user data (recents/icons/review state) is touched.
- Verified against the real broken DB: v1 checksum healed, v2 then applied,
  session restore + persistence work, no console error.
- sqlx + sha2 added as direct deps (already in the tree via tauri-plugin-sql).

Verified: cargo check, cargo clippy -p strand-tauri -- -D warnings, tsc -b
(via tauri build), and an end-to-end CDP run of both the perf measurements
and the migration heal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@danielss-dev danielss-dev merged commit c06f05d into main Jun 29, 2026
2 checks passed
@danielss-dev danielss-dev deleted the perf/webview-baseline-and-migration-heal branch June 29, 2026 20:30
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