Skip to content

perf(rendering): remove avoidable redraws, mirrored state, and unstable propagation #121

Description

@codeacme17

Parent

#114

Summary

Remove avoidable redraws, mirrored state, unstable context propagation, and layout-heavy work from the remaining Echo UI components and shared rendering infrastructure.

This issue collects lower-frequency performance problems that do not justify separate tickets but still cause extra commits, observer work, full redraws, or expensive paint behavior across the library.

Scope

Resize scheduling

  • Replace the current resize throttle behavior with a cancellable scheduler.
  • Avoid an unconditional trailing invocation when no additional resize occurred.
  • Keep the latest callback available without recreating observers for ordinary data changes.
  • Disconnect observers and cancel pending work on cleanup.
  • Ensure one stable resize event results in one redraw.

LFO and low-frequency visual rendering

  • Make LFO sampling resolution-aware instead of always generating a fixed large point set.
  • Coalesce resize and redraw work.
  • Reuse stable SVG structure, scales, and geometry configuration.
  • Avoid synchronous computed-style reads in Light and other render hot paths.
  • Review heavy paint effects and provide an equivalent lower-cost path where necessary.
  • Prefer transform and opacity for animated presentation over layout properties.

Controlled state and render waterfalls

  • Remove prop values mirrored into state when they can be derived directly.
  • Eliminate render-phase state setters and effect-only synchronization renders.
  • Cover Button, Checkbox, Radio, Switch, Light, and other affected controls.
  • Preserve controlled and uncontrolled contracts.
  • Ensure React Strict Mode produces no render-phase update warnings.

Context and class generation

  • Memoize group context values and stabilize group handlers.
  • Prevent unrelated group children from rerendering when inherited values are unchanged.
  • Avoid repeating static class-merging work inside frame-driven or frequently updated components.
  • Precompute stable style-slot output outside hot paths where practical.

Axis and measurement

  • Reduce avoidable two-stage measurement and full axis recreation.
  • Rebuild axes only when dimensions, domain, scale, ticks, or formatting inputs change.
  • Prevent audio-frame data changes from rebuilding static axis layers.

Acceptance criteria

  • One stable ResizeObserver notification produces one scheduled redraw.
  • Observer callbacks and pending timeouts are canceled on unmount.
  • Ordinary data changes do not recreate ResizeObserver subscriptions.
  • LFO sampling scales with rendered resolution and does not always allocate a fixed 1,000-point representation.
  • Stable LFO structure is reused across ordinary value updates.
  • Controlled prop updates require no more than one necessary component commit.
  • No state setter runs during render or a render-time memo calculation.
  • Stable group props preserve context identity and do not rerender unrelated children.
  • Static class-generation work is absent from identified real-time hot paths.
  • Static axes are not recreated by audio-frame updates.
  • Layout-property animations identified by the audit are replaced or justified.
  • Light and other paint-heavy components retain their intended appearance within the agreed rendering budget.
  • Public props, group inheritance, and controlled/uncontrolled behavior remain compatible.

Out of scope

  • Package export restructuring.
  • Real-time analyzer and visualizer internals.
  • Waveform preprocessing and rendering.
  • Pointer scheduling owned by the controls interaction issue.
  • Broad visual redesign.

Validation

  • Add focused render-count, observer-cleanup, context-identity, and resize-scheduling tests.
  • Validate React Strict Mode behavior.
  • Measure LFO, Light, group-heavy pages, and axis-bearing visualizations.
  • Run visual regression or representative screenshots for appearance-sensitive paint changes.

Dependencies

Blocked by: #115.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions