Skip to content

feat(perf): improve playlist responsiveness and playback rendering - #72

Merged
rianjs merged 26 commits into
mainfrom
codex/tauri-performance-experiments
Sep 10, 2026
Merged

rianjs merged 26 commits into
mainfrom
codex/tauri-performance-experiments

Conversation

@rianjs

@rianjs rianjs commented Sep 10, 2026 •

Copy link
Copy Markdown
Collaborator

Large playlists previously mounted every row, and elapsed playback updates repeatedly rendered the surrounding Library and playlist views. This change isolates transport progress, windows playlist rows, pauses hidden presentation, removes redundant startup/settings work, loads the selected window's code, and stops superseded importer refreshes. The largest measured gains are in playlist responsiveness and reduced React work.

Stepwise measurements

Each experiment was measured separately before and after its change, with three samples per comparison. Values below are medians; browser fixtures, filesystem microbenchmarks, and native measurements are separate experiments.

Change Before → after Interpretation
Isolate elapsed playback updates Library React work over 12 ticks: 303.4 → 9.8 ms; playlist: 3,932.9 → 9.0 ms Large reduction in unnecessary rendering; repeated playlist long tasks disappeared in the fixture
Window playlist rows and memoize order/queue Browser playlist opening: 769.7 → 32.0 ms; selection: 350.3 → 31.8 ms; mounted rows: 4,100 → 47–48 Full queue and upstream indices remain available for selection, playback, and mutations
Pause hidden presentation Hidden React work over 12 ticks: 8.2 → 0 ms, with zero commits after the change Latest elapsed state is retained; title animation pauses while hidden
Skip redundant startup settings writes Existing-settings load: 4.812 → 0.045 ms per invocation Removes an unnecessary atomic write; missing/default settings still require a write and showed no improvement
Load only the selected window entry Required JavaScript: 446,859 → 377,118 bytes for main / 377,075 for importer; gzip: 130,008 → 112,673 / 112,533 bytes About 13.3% less gzip JS per window; no demonstrated startup latency improvement
Move startup file hydration off the caller Synchronous caller occupancy: 10.448 ms → <0.013 ms; file readiness: 10.448 → 9.463 ms, with overlapping ranges Changes scheduling, not demonstrated data-readiness speed; IPC waits for recovery/state publication
Stop superseded importer refreshes Six-invalidation burst over 8,000 batches: 48 → 13 page calls, 15,850,986 → 4,283,276 bytes 73% less request/byte work in the fixture; latest-result latency unchanged at 172.7 → 173.1 ms

The importer still loads the complete current queue. Obsolete requests finish their pending page and stop before fetching more; existing publication guards reject stale results.

Native WebKit measurements

Release-mode Tauri builds compared the pre-step-1 baseline (8868b59) with the combined final implementation (fea5335, packaged from ebaf788). Both used the real App and IPC, the same generated 4,000-track local Library and 4,100-entry playlist, and a 1120×688 content viewport. Host: Apple M4 Pro, 48 GiB RAM, macOS 26.6.2, WebKit 21624.5.1.11.3. Playback used digital silence at volume zero; no Spotify or Last.fm account was involved.

Native action Before median After median
Open playlist 785 ms 45 ms
Select first entry 261 ms 33 ms
End 61 ms 33 ms
Shift+Home 125 ms 33 ms
Sort by song 707 ms 33 ms
Scroll to middle 31 ms 34 ms

Three samples per action. Mounted rows fell from 4,100 to 45–46. Measurements wait for populated rows where needed and two animation frames, producing an approximately 33 ms floor; they are not direct hardware scanout timings. This native comparison measures the combined changes, not each step's native contribution.

Three warm launches per variant, after discarding the initial launch, measured process start to populated Library plus two frames: 607.6 ms before (594.5–666.1), 616.4 ms after (604.1–638.3). There is no demonstrated startup improvement; these are not cold-storage measurements.

Paused CPU and memory observations after the playlist workload:

Window state Before CPU After CPU Before summed footprint After summed footprint
Visible 0.74% 0.73% 351.8 MiB 145.4 MiB
Hidden 0.74% 0.90% 349.6 MiB 145.8 MiB
Minimized 0.82% 1.10% 207.5 MiB 149.1 MiB

CPU 100% represents one core. Each state has three consecutive five-second samples covering the app and its attributed WebKit services. No idle CPU saving was demonstrated. Lower footprint snapshots are encouraging but depend on garbage collection and window state: these are single-process-lifetime observations, not independent memory trials, unique system memory, or peak usage. The paused CPU scenario did not exercise an actively scrolling title.

Validation and evidence

  • Recorded local checks passed: Rust workspace tests, formatting and Clippy; startup release regressions/benchmarks; 96 Node checks and 76 Vitest tests (8 existing manual benchmarks skipped); frontend lint/build; Tauri ACL/permissions, release-contract, and documentation checks; native release bundle builds.
  • Regression/browser checks cover duplicate playlist entries, global keyboard selection and drag indices, importer filtering/selection through batch 8,000, stale refreshes, startup recovery/publication, selected-window resources, and dark/narrow layouts.
  • Native checks passed for signed-out local playback, automatic pause after five seconds, elapsed refresh on show, title animation pause/resume when hidden or minimized, and normal shutdown with attributed processes exiting.
  • Physical media keys, OAuth, account-bound importer IPC, cold storage, other operating systems, and deliberately stalled native startup/exit races were not tested. Measurements are local observations, not an authenticated evidence-registry certification.

Full measurement protocol, per-step revisions, assessment, and raw JSON.

@rianjs rianjs changed the title Codex/tauri performance experiments feat(perf): Codex/tauri performance experiments Sep 10, 2026
@rianjs rianjs changed the title feat(perf): Codex/tauri performance experiments perf: improve playlist responsiveness and playback rendering Sep 10, 2026
@rianjs rianjs changed the title perf: improve playlist responsiveness and playback rendering feat(perf): improve playlist responsiveness and playback rendering Sep 10, 2026
@rianjs rianjs closed this Sep 10, 2026
@rianjs rianjs reopened this Sep 10, 2026
@rianjs
rianjs merged commit 998efb2 into main Sep 10, 2026
9 of 16 checks passed
@rianjs
rianjs deleted the codex/tauri-performance-experiments branch September 10, 2026 09:29
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