Skip to content

frontend goes vroom - #4436

Merged
joaoantoniocardoso merged 9 commits into
bluerobotics:masterfrom
patrickelectric:frontend-goes-vrooom
Sep 14, 2026
Merged

frontend goes vroom#4436
joaoantoniocardoso merged 9 commits into
bluerobotics:masterfrom
patrickelectric:frontend-goes-vrooom

Conversation

@patrickelectric

Copy link
Copy Markdown
Member

Helps #4434

Improve:

  • zenoh page
  • one_more_time leaks
    • ping page
    • main page
    • backend status
    • wizard
  • decrease video overview update rate (from 1s to 5s)

Results:

solved-01-cpu-mean solved-02-cpu-peak solved-03-process-breakdown solved-04-network-vehicle-setup solved-05-poller-leak solved-06-heap-peak solved-07-zenoh-invariants solved-08-dev-vs-prod-calibration solved-09-summary-all-fixes

The option was typed as `unknown`, so `disposeWith: this` inside an
arrow function `data` type checks while `this` is the module scope,
and the task keeps running after the component is destroyed.

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
`this` inside an arrow function is the module scope, not the component,
so the task was never disposed and every visit to the page left another
serial port poller running.

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
`this` inside an arrow function is the module scope, not the component,
so the task would never be disposed if MainView is ever destroyed.

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
…nction

`this` inside an arrow function is the module scope, not the component,
so the task would never be disposed if the component is ever destroyed.

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
…nction

`this` inside an arrow function is the module scope, not the component,
so closing the wizard left the board check running.

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
…s every 5s

Each request returns 455 KB and the device list only changes when
hardware is plugged in, so polling every second was moving 130 MB
every five minutes.

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
The topic list reaches a few hundred entries on a vehicle and the scan
ran once per arriving sample, at over a thousand samples per second.

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
…rame

Every sample went straight into a reactive map, so Vue flushed a render
for each one, at over a thousand samples per second.

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
@patrickelectric
patrickelectric requested a review from a team September 12, 2026 01:33
@github-actions

Copy link
Copy Markdown

Automated PR Review

0. Summary

  • Verdict: MINOR SUGGESTIONS ✏️

Fixes a memory leak in several Vue components that were using the arrow-function data: () => ({...}) form with disposeWith: this, where this did not point at the component instance and OneMoreTime therefore never got disposed. Also adds requestAnimationFrame batching + markRaw to ZenohInspector, drops VideoOverview polling from 1 s to 5 s, and adds a runtime warning in OneMoreTime when disposeWith is not a real component instance.

1. Correctness & Implementation Bugs

  • 1.1 [minor] core/frontend/src/components/wizard/DefaultParamLoader.vue:116 — same bug the PR is fixing elsewhere is still present here: data: () => ({ ..., fetch_current_board_task: new OneMoreTime({ delay: 10000, disposeWith: this }) }). With the arrow form, this is the module scope, so _isDestroyed is never observed and the task leaks for the lifetime of the tab. The new console.warn you added in one-more-time.ts will actually fire on this file at runtime — worth folding it into the same PR so the warning shipped with this PR doesn't yell about a leak the PR doesn't fix.

4. Performance

  • 4.1 [nit] core/frontend/src/components/zenoh-inspector/ZenohInspector.vue:257-ish — the batching path is a real improvement, but note that this.$set(this.messages, topic, batch[topic]) inside flushStagedMessages still fires one reactive write per topic per frame. If the frame contains many new topics the resulting re-render can still dominate; a future optimization would be to swap this.messages for a new object once per flush (single reactive write) rather than N $set calls. Non-blocking, just a follow-up idea.

6. Code Quality & Style

  • 6.1 [nit] core/frontend/src/one-more-time.ts:41 — narrowing disposeWith?: unknown to disposeWith?: { _isDestroyed?: boolean } is a nice targeted type, but it happens to be structurally satisfied by lots of non-Vue objects (anything without _isDestroyed, or with an _isDestroyed typed as boolean | undefined, matches). If you want the compiler — not just console.warn — to catch bad call sites, a nominal marker (ComponentPublicInstance from vue, or a branded type) would do it. Optional.
  • 6.2 [nit] core/frontend/src/components/zenoh-inspector/ZenohInspector.vue:247isKnownTopic now checks messages and topic_liveliness but not topics itself. That's fine given the current flow (every entry in topics is also in one of those two maps), but the invariant is implicit; a one-line comment on isKnownTopic calling that out would save the next reader some head-scratching.

8. Documentation

  • 8.1 [nit] The three inline comments on staging in ZenohInspector.vue (markRaw, keyed by topic, null-prototype) are exactly the kind of "why" that AGENTS.md asks for — good. Same for the "before $set fills the map isKnownTopic reads" comment in the liveliness callback: it directly explains the load-bearing reordering. Nothing to change, just calling it out so it doesn't get "cleaned up" later.

Generated by PR Review Bot. This is advisory, a human reviewer must still approve.

…row function

`this` inside an arrow function is the module scope, not the component,
so closing the wizard left the board check running.

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
@joaoantoniocardoso
joaoantoniocardoso merged commit 53678f8 into bluerobotics:master Sep 14, 2026
7 checks passed
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