Skip to content

Finalize part3 performance pass with Worker preprocessing, WebAssembly note math, and activation diagnostics#16

Merged
7effrey89 merged 13 commits into
mainfrom
copilot/add-web-worker-offload
May 31, 2026
Merged

Finalize part3 performance pass with Worker preprocessing, WebAssembly note math, and activation diagnostics#16
7effrey89 merged 13 commits into
mainfrom
copilot/add-web-worker-offload

Conversation

Copilot AI commented May 17, 2026

Copy link
Copy Markdown
Contributor

This PR completes the remaining optimization work from the prior performance pass by offloading heavy note preprocessing and adding a WebAssembly-backed fast path for repeated note-height math. Existing GPU note rendering remains in place and is now paired with lower main-thread preprocessing cost, plus runtime diagnostics to verify optimization activation.

  • Web Worker offload for song preprocessing

    • Added performance-worker.js to precompute:
      • BPM estimate
      • simple-mode merged notes
      • normal/simple song durations
    • app.js now asynchronously requests this precompute during song load/upload flows and applies cached outputs in applyGameMode().
    • Worker request handling now includes pending-cleanup on postMessage failure and request timeout handling to avoid stuck pending tasks.
  • WebAssembly hot-path optimization

    • Added note-math.wasm with exported math functions for note height calculation.
    • Added wasm bootstrap + safe JS fallback in app.js.
    • Replaced repeated Math.max(12, dur * noteSpeed * speed...) logic in hot render/update paths with shared helpers.
  • Mode/duration caching integration

    • Introduced _simpleModeCache and _durationCache to avoid recomputing merged-note timelines on mode switches.
    • applyGameMode() now consumes cached precompute output when available.
  • Activation/verification diagnostics

    • Added live runtime status text in UI (settings + header) to show:
      • Worker status (init/ready/error/unsupported)
      • WASM status (init/ready/error/fetch-failed/unsupported)
      • Precompute mode (worker/mixed/fallback) and elapsed time
    • Added console timing logs for each precompute run to make optimization behavior measurable on real songs.
  • Asset wiring

    • Bumped app.js cache-bust version in index.html to pick up runtime changes.
// Worker-backed precompute on load
this.originalNotes = data.notes;
await this._precomputeSongData(data.notes);
this.applyGameMode();

// WASM-backed hot-path helper with fallback
_visibleNoteHeight(duration, speedMultiplier) {
  const dur = duration || 0.15;
  if (this._wasmMath?.note_visible_height) {
    return this._wasmMath.note_visible_height(dur, this.noteSpeed, speedMultiplier);
  }
  return Math.max(12, dur * this.noteSpeed * speedMultiplier);
}

Copilot AI linked an issue May 17, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add Web Worker offload for performance improvements Finalize part3 performance pass with Worker preprocessing and WebAssembly note math May 17, 2026
Copilot AI requested a review from 7effrey89 May 17, 2026 08:42
@7effrey89
7effrey89 requested a review from Copilot May 17, 2026 12:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes the “part3 performance pass” by moving song preprocessing work off the main thread into a Web Worker and introducing a WebAssembly-backed fast path for repeated note-height calculations during rendering.

Changes:

  • Added performance-worker.js to precompute BPM, merged notes for simple mode, and durations in a worker.
  • Updated app.js to request/apply worker-precomputed caches and to use WASM-backed helpers (with JS fallback) for note height math.
  • Bumped app.js cache-bust version in index.html.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
performance-worker.js New worker that precomputes BPM, simple-mode merged notes, and durations.
app.js Initializes worker + WASM, adds caches for precompute output, and routes hot-path note height math through shared helpers.
index.html Updates app.js query-string version to pick up the runtime changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app.js Outdated
Comment on lines +285 to +295
async _precomputeSongData(notes) {
const safeNotes = Array.isArray(notes) ? notes : [];
this._simpleModeCache = null;
this._durationCache = null;
let bpm = this.estimateBPM(safeNotes);
let normalDuration = 0;
for (let i = 0; i < safeNotes.length; i++) {
const n = safeNotes[i];
const end = n.time + (n.duration || 0.15);
if (end > normalDuration) normalDuration = end;
}
Comment thread app.js Outdated
return new Promise((resolve, reject) => {
const id = ++this._perfWorkerReqId;
this._perfWorkerPending.set(id, { resolve, reject });
this._perfWorker.postMessage({ id, task, payload });
@7effrey89

Copy link
Copy Markdown
Owner

@copilot Fix according to the pr reviews

Copilot AI commented May 17, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Fix according to the pr reviews

Implemented the review fixes in e680cc2.

  • _runPerfWorkerTask() now cleans pending entries on postMessage failure and adds a timeout so requests can’t stay pending indefinitely.
  • _precomputeSongData() now avoids the duplicate upfront O(n) main-thread scans and only performs synchronous BPM/duration loops in fallback paths when worker output is unavailable/incomplete.

I couldn’t attach a UI screenshot here because the Playwright browser profile is locked in this environment (mcp-chrome lock error).

@7effrey89

Copy link
Copy Markdown
Owner

@copilot
image
i do not experience a significant performance improvement for songs with many nodes like the one on the screenshot (pokemon theme.mid).

how would we verify that all the optimizations have been implemented and activated?

Copilot AI commented May 17, 2026

Copy link
Copy Markdown
Contributor Author

@copilot
image
i do not experience a significant performance improvemen...

Good callout — with dense songs, the biggest cost can still be per-frame draw/update work, so load-time optimizations may feel subtle during playback.

To verify optimizations are active right now:

  1. Worker path active
  • DevTools → Network: confirm performance-worker.js?v=1 loads.
  • DevTools → Sources: a dedicated Worker thread should appear.
  • Record a Performance trace while loading a heavy MIDI: main thread should not spend most preload time inside simplify/duration loops.
  1. WASM path active
  • DevTools → Network: confirm note-math.wasm?v=1 loads (200).
  • In a Performance trace during playback, JS self-time in note-height math should be reduced vs pure JS fallback.
  1. Fallback detection
  • If worker/wasm fail, code silently falls back to JS. In DevTools, failed requests for performance-worker.js or note-math.wasm indicate fallback is being used.

If you want, I can add a small debug indicator (e.g., in settings or console) showing Worker: on/off and WASM: on/off plus precompute timing, so activation is explicit and measurable on your machine.

@7effrey89

Copy link
Copy Markdown
Owner

@copilot yws please do that

Copilot AI commented May 17, 2026

Copy link
Copy Markdown
Contributor Author

@copilot yws please do that

Implemented in 62f47ee.

Added a live diagnostics indicator showing Worker/WASM activation state and precompute mode/time, plus console timing logs per precompute run.

perf debug indicator

Copilot AI changed the title Finalize part3 performance pass with Worker preprocessing and WebAssembly note math Finalize part3 performance pass with Worker preprocessing, WebAssembly note math, and activation diagnostics May 17, 2026
@7effrey89

Copy link
Copy Markdown
Owner

ADD to features and readme about all these optimization from previous and current pr and how to verify their activation @copilot

Copilot AI commented May 17, 2026

Copy link
Copy Markdown
Contributor Author

ADD to features and readme about all these optimization from previous and current pr and how to verify their activation @copilot

Implemented in b4419d7.

Added documentation in both README.md and features.md covering the optimization stack (Worker preprocessing, WASM note math, cache reuse, diagnostics) and clear activation verification steps (UI perf indicator, console timing logs, and optional DevTools network checks).

@7effrey89
7effrey89 merged commit 5396344 into main May 31, 2026
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.

part3 performance

3 participants