Skip to content

perf(player): cut wasted per-frame rebuilds during playback#1019

Open
JenteJan wants to merge 1 commit into
DonutWare:developfrom
JenteJan:perf/player-optimizations
Open

perf(player): cut wasted per-frame rebuilds during playback#1019
JenteJan wants to merge 1 commit into
DonutWare:developfrom
JenteJan:perf/player-optimizations

Conversation

@JenteJan

@JenteJan JenteJan commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Pull Request Description

Three rebuild-scope cleanups in the video player. No behaviour change — purely doing less redundant work during playback.

  1. Unmount the overlay controls while hidden. They were kept mounted at opacity: 0 when auto-hidden, so their position-driven Consumers kept rebuilding (~1–2×/sec from position ticks) the whole time you're just watching. Now dropped from the tree once the hide animation finishes, and remounted before fading back in.
  2. Only build the scrub-preview card while it's visible. chapterCard built and laid out its image / TrickPlayImage subtree on every frame behind opacity: 0. For trickplay-enabled content this means laying out a preview tile every frame even when it isn't shown. Now gated on actual hover/drag.
  3. Narrow the queue watches. The audio queue + queue dialog watched the whole mediaPlaybackModel and re-.map()-ed the entire queue on every position tick; they only need repeatMode, so they now select() just that.

Issue Being Fixed

General playback efficiency — no specific issue.

Screenshots / Recordings

N/A — no visual change.

Tested On

  • Android
  • Android TV
  • iOS
  • Linux
  • Windows
  • macOS
  • Web

Checklist

  • No new packages added.
  • Changes are scoped to player rebuild behaviour.

Verification / honesty notes:

  • Profiled in profile mode on macOS (the media_kit/libmpv desktop path, shared with Windows). The render pipeline is jank-free in every scenario (raster p99 < ~1ms), so this is not a dropped-frame fix — it removes wasted CPU/GC/main-thread work, with benefit scaling on trickplay-heavy content and weaker hardware. No fabricated fps numbers.
  • (1) was exercised at runtime + profiled; (2)/(3) are analyzer-clean refactors.

Profiling steady-state playback on macOS (libmpv path, shared with
Windows) showed the Flutter layer doing needless work while watching,
even though the video itself is composited cheaply by mpv.

- Unmount the overlay controls once their hide animation finishes, so
  their position-driven Consumers stop rebuilding while the overlay is
  hidden (the common 'just watching' case). Remount before fading back
  in. Steady-state UI work drops to ~3 idle frames/sec.
- Only build the progress-bar scrub-preview card while it is actually
  visible; it was building and laying out its image/trickplay subtree on
  every frame behind opacity 0 (the dominant LAYOUT cost when controls
  are shown).
- Narrow the audio queue / queue-dialog watches to repeatMode via
  select() instead of watching the whole playback model, so they no
  longer rebuild and re-map the entire queue on every position tick.

No behavioural change; pure rebuild-scope reduction.
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