Skip to content

perf: batch panel resize reads/writes, debounce mastery-slider prefs saves - #31

Merged
carochacs merged 1 commit into
mainfrom
claude/performance-improvements-kfow1s
Aug 17, 2026
Merged

perf: batch panel resize reads/writes, debounce mastery-slider prefs saves#31
carochacs merged 1 commit into
mainfrom
claude/performance-improvements-kfow1s

Conversation

@carochacs

Copy link
Copy Markdown
Collaborator

Summary

Two verified performance fixes, no behavior change:

  1. Layout thrashing in panel resizesizeCanvases() and the two window-resize handlers that mirror its shape looped over panels doing a getBoundingClientRect()/offsetHeight read immediately followed by canvas style/width/height writes, then read again for the next panel — forcing a synchronous layout recalc every iteration (worst on tri/quad/five/six layouts, up to 6 panels). hw.resize() now takes an optional precomputed {rect, barH}, and the resize call sites measure every panel first, then apply all writes in a second pass — one layout flush instead of N.
  2. Un-debounced localStorage write on slider drag — the mastery slider's oninput called savePanelPrefs() on every tick during a drag, which stringifies prefs for every panel (calling hw.getInverted()/getLefty()/getMastery() etc.) and writes to localStorage — potentially dozens of times per drag. Added savePanelPrefsDebounced() (300ms coalescing); the slider handler now uses it. savePanelPrefs() itself cancels any pending debounce timer so every existing direct call site (including stopSplitScreen's teardown-time save) still wins and flushes immediately, avoiding a stale debounced write clobbering splitscreenPanelPrefs after teardown.

Also audited (per CLAUDE.md's documented behavior) and confirmed already correct, no change needed: the popup/LAN time broadcaster's popups.size === 0 && !_lanShare gate, and startTimeSync's 60fps loop (no redundant DOM queries inside it).

Bumped plugin.json version 1.14.21.14.3 (patch), matching this repo's established convention.

Testing

  • node -c screen.js — clean
  • node tests/screen.test.js — 33/33 passing, before and after

Generated by Claude Code

sizeCanvases() (and the two window-resize handlers that mirror its loop
shape) called getBoundingClientRect()/offsetHeight for panel N right
after panel N-1's canvas-size writes, forcing a synchronous layout
recalc on every iteration — worst on tri/quad/five/six layouts. hw.resize
now accepts an optional precomputed {rect, barH} so callers that resize
several panels in one pass can measure everything first, then apply all
the writes, costing one layout flush instead of one per panel.

The mastery slider's oninput handler also called savePanelPrefs()
(JSON.stringify + localStorage.setItem over every panel) on every
`input` tick while dragging. It now goes through a new
savePanelPrefsDebounced(), coalescing rapid drags into a single write
~300ms after the last change. Any direct savePanelPrefs() call (e.g.
stopSplitScreen's teardown) still cancels a pending debounced write, so
a stale timer can't fire after `panels` has been reset to [].

Bump plugin.json to 1.14.3 (patch) per this repo's versioning
convention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f2b8ad7f-7f26-4d0f-838c-7b83d568d449

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pullfrog pullfrog Bot 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.

✅ No new issues found.

Reviewed changes — this review covers commit 1eb1096 against main.

  • Layout-thrashing elimination in sizeCanvases() — the main-window resize path now batches every panel's getBoundingClientRect()/offsetHeight reads into a measured array before any canvas-size writes, collapsing N forced layout flushes into one. hw.resize() accepts an optional precomputed {rect, barH} and falls back to self-measuring for single-panel callers.
  • Same batching in follower window resize handler — the buildFollowerLayout resize listener mirrors the pattern for multi-panel popups.
  • Debounced mastery-slider prefs savesavePanelPrefsDebounced() (300 ms coalescing) replaces the per-tick savePanelPrefs() in the slider's oninput. savePanelPrefs() itself clears any pending debounce timer, so teardown-time saves and every other direct call site still flush immediately without risk of a stale write clobbering state.
  • Plugin version bump1.14.21.14.3 patch.

Pullfrog  | View workflow run | Using Big Pickle (free) | 𝕏

@carochacs
carochacs merged commit 06b80e8 into main Aug 17, 2026
7 checks passed
@carochacs
carochacs deleted the claude/performance-improvements-kfow1s branch August 17, 2026 21:56
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.

2 participants