Skip to content

Fix hot-path redraw churn#124

Open
yo3gnd wants to merge 4 commits into
openhamclock:mainfrom
yo3gnd:yo3gnd-hotpath-fixes-main
Open

Fix hot-path redraw churn#124
yo3gnd wants to merge 4 commits into
openhamclock:mainfrom
yo3gnd:yo3gnd-hotpath-fixes-main

Conversation

@yo3gnd

@yo3gnd yo3gnd commented May 8, 2026

Copy link
Copy Markdown
Contributor

This is the main slice of the original broader CPU/load PR #122 - split out for easier review. This branch contains only the core redraw/runtime change and fixes #121

It keeps the core redraw/runtime change together: stop the continuous repaint loop, preserve prompt redraws where the old code had been relying on “another sweep will happen in a moment anyway”, and keep a conservative periodic refresh for slow-moving overlays. The -L knob and the two tiny follow-up cleanups are left to separate branches so this one stays focused on the main behavioural fix.

@komacke komacke requested a review from wasatch-dev May 8, 2026 21:13
Tighten the lazy map redraw path for liveweb interaction.

- clear queued websocket taps in drainTouch() so stale clicks are not replayed after a menu or popup closes
- treat the map popup and view menu as modal so mouse-hover redraws do not invalidate the map underneath them while they are open
- redraw the protected region immediately when a map-overlapping menu closes, instead of waiting for a later sweep to publish the restored pixels
- promote deferred mouse redraws as soon as their throttle window expires, even when no sweep is active
- always paint the city-name black backing strip before drawing the label, so fast land/water/land hover transitions do not leave white text over map pixels

This keeps the CPU-saving lazy redraw model, but fixes the UI regressions it introduced for liveweb hover and map-menu interaction.
@yo3gnd

yo3gnd commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

This last commit exists because the hot-path work was right in principle, but it exposed a nest of liveweb assumptions that only held while the map was being redrawn all the bloody time. Once redraws became lazy, menus could vanish without being properly repainted, stale websocket taps could come back from the dead, hover redraws could meddle with modal UI, and the city label occasionally forgot to bring its black backdrop with it. In other words: the optimisation was sound, but it still wanted the unglamorous follow-up work that stops a clever change from downgrading UX.

Visually confirmed regression was fixed on: 800, 1600, 2400, 3200 on all 4 projections plus 3 zoom levels. As expected, the CPU ramps up when you play agitated cartographer, and it goes back down without mouse input. I believe this is a fair trade for the user.

@komacke

komacke commented May 21, 2026

Copy link
Copy Markdown
Collaborator

I'm not seeing significant CPU reduction on a machine web-HC running in a docker container and 2 browser clients connected to it. Would you expect a significant reduction in load in this case?

I don't think we should mess significantly with the implementation unless the improvement is significant.

@yo3gnd

yo3gnd commented May 22, 2026

Copy link
Copy Markdown
Contributor Author

There is a bit more background in #122, but I do think any PR in this area will inevitably touch rather a lot of files. Once the map stops being redrawn in a brute-force loop, a good many call sites need to become explicit about asking for invalidation and redraw. That is not especially elegant, but it is the shape of the problem.

On my dev env, with the app left in standby and no mouse activity, this branch idles at roughly 5% of one core, whereas the master branch was sitting nearer 70% under the same sort of conditions. I am therefore fairly comfortable calling the reduction significant. After about eight minutes of runtime, I see only about twenty seconds of accumulated CPU time:

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root     1260718  4.9  0.2 329308 23220 pts/7    Ssl+ 08:02   0:20 ./hamclock-web-1600x960 -k -b ohb.hamclock.app:80

If you are not seeing a similar drop, I do wonder whether we may not be measuring quite the same thing. This branch is rather sensitive to build state and runtime conditions: I would strongly suggest checking it out into a fresh worktree, or at the very least doing a clean build so all objects are rebuilt with the current flags and code. It is also worth comparing like with like: I just left the machine idling, with no mouse input. I do not mean that as a rebuttal, merely that there are a few moving parts here, and it would be good to make sure we are all tormenting the same machine in the same way.

@yo3gnd

yo3gnd commented May 25, 2026

Copy link
Copy Markdown
Contributor Author

One small detail that may not have been obvious: all my tests were done, as stated at the outset, with throttling disabled (no -t 10) since that is precisely the behaviour I am trying to optimise away. If throttling is left enabled, then we are no longer measuring the same thing, and the comparison becomes rather less useful.

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.

Desktop/web build burns CPU by continuously redrawing the map

2 participants