e29b7ed3d3
Chrome classifies wheel events as "pointer" interactions and tracks async
continuations initiated by the handler. The wheel-on-freq-input path was:
jogFreq → setRigFrequency → postPath(/set_freq) [~700ms]
→ ensureTunedBandwidthCoverage [~700ms]
...two sequential network round-trips totalling ~1400ms of INP.
Three changes:
1. yieldToMain(): add a scheduler.yield() / setTimeout(0) helper that
yields the main thread back to the browser. Chrome's INP interaction
tracking ends at the yield point, so the network RTT no longer counts.
2. jogFreq: call applyLocalTunedFrequency() optimistically before the
yield so the freq display updates are visible in the very next paint,
then yield before firing any network requests.
3. setRigFrequency: move applyLocalTunedFrequency() before the awaits
(consistent optimistic-update contract for all callers), and run
postPath(/set_freq) and ensureTunedBandwidthCoverage() in parallel
via Promise.all — they are independent server operations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>