Skip to content

perf(waveform): optimize peak generation, caching, and rendering #119

Description

@codeacme17

Parent

#114

Summary

Optimize the complete waveform pipeline: peak generation, caching, geometry reuse, progress rendering, hover interaction, resize handling, and cancellation.

Waveform processing currently performs synchronous work over PCM frames and renders duplicate geometry for progress masking. Progress and hover behavior can also trigger repeated layout reads, state updates, and large SVG path work. Treating preprocessing and rendering as one issue makes it possible to validate the end-to-end long-audio experience.

Scope

Peak generation

  • Move long-audio peak extraction off the main thread when Worker execution is available.
  • Provide chunked, yielding processing when Worker execution is unavailable.
  • Cancel obsolete work when the source, resolution, or component lifecycle changes.
  • Cache peak results by the inputs that materially affect the output.
  • Reuse compatible peak levels when visualization width changes.
  • Avoid rerunning preprocessing for progress, hover, or styling changes.

Rendering

  • Reuse a single waveform geometry where possible.
  • Use a clip path, mask, or equivalent lightweight mechanism for playback progress.
  • Avoid animating large path-data attributes during initialization.
  • Update cursor and progress presentation through transform or clipping rather than rebuilding geometry.
  • Respect reduced-motion preferences.

Interaction and resize

  • Cache component bounds during pointer entry, resize, or another stable lifecycle boundary.
  • Avoid calling layout measurement APIs on every pointer move.
  • Coalesce hover and cursor updates to one publication per animation frame.
  • Avoid multiple independent React state updates for one pointer sample.
  • Use cancellable resize scheduling with no unconditional trailing redraw.

Acceptance criteria

  • Long-audio peak generation does not create a main-thread task longer than 50 ms on the agreed benchmark environment.
  • Switching back to a previously processed compatible source reuses cached peak data.
  • Changing playback progress does not rerun peak extraction.
  • Playback progress does not rebuild waveform path geometry.
  • Hover movement does not perform a layout read for every pointer event.
  • Cursor movement uses a transform-only or equivalent compositor-friendly update.
  • A progress tick produces no more than one React commit.
  • Resize work is cancellable and one stable resize produces one redraw.
  • Obsolete preprocessing results cannot overwrite results for a newer source.
  • Unmount cancels Worker, scheduled, observer, and interaction work.
  • Reduced-motion behavior is covered.
  • Visual output, seeking, progress, channel handling, and controlled behavior remain compatible.

Out of scope

  • Audio fetching and decoding cache ownership.
  • Oscilloscope, Spectrogram, and VU Meter.
  • Redesigning the waveform API.
  • Requiring Worker support in every environment.

Validation

  • Test short, long, mono, stereo, cached, replaced, failed, and canceled audio sources.
  • Test progress updates without pointer activity and hover activity without playback.
  • Test resize storms, document visibility changes, reduced motion, and unmount during preprocessing.
  • Compare main-thread tasks, React commits, layout reads, and SVG mutations against the baseline.

Dependencies

Blocked by: #117.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions