Skip to content

signals: fix and improve the Signals inspector from the October 2026 audit #319

Closed as duplicate

Description

@erkamyaman

Context

This comes from a code audit of the Signals inspector (signal graph, write history, peeks, inspect-signals and the Signals page), done during a comparison with other devtools in October 2026. Roadmap items live in #310, #311, #312 and #313. Items marked (to confirm) were not reproduced.

Problems

Medium

  • Write hook cost: the write hook serializes every write to every named signal, even when no panel or agent is listening and the signal is not in the reported graph. Hot signals (pointer position, animation frames, typing) pay serialize synchronously inside Angular's set path. Keep the raw value and version on write and serialize lazily in collect() only for tracks bound to graph nodes, or keep only the latest value per track per microtask (packages/devtools/src/signal-history.ts:58-63, installed in packages/devtools/src/overlay.ts:250).
  • Unnamed writes dropped silently: onWrite returns early when node.debugName is missing, so those signals get only sample history and nothing says why. Only resources show a debugName hint. Add the same hint on (unnamed) cards and on histories with only sampled entries, and say which Angular version adds names automatically (packages/devtools/src/signal-history.ts:42-43, app/src/pages/signal-inspector.ts:384, :485).

Low

  • Track eviction is FIFO, not LRU: tracks.delete(tracks.keys().next().value!) evicts the oldest created track, and existing tracks are never re-inserted on write, so a signal written constantly loses its exact history once 500 newer signals exist. Re-insert on write and prefer tracks whose WeakRef is dead (packages/devtools/src/signal-history.ts:56).
  • History owner ignores injectors: the delta owner is graph.component?.id ?? '', so switching between environment injector graphs sends a delta, and the server merges prev?.history?.[id] by node id without checking the owner. Use graph.component?.id ?? graph.injector?.id ?? '', and drop the previous history on the server when the owner changed (packages/devtools/src/overlay.ts:271, packages/devtools/src/devframe.ts:1446-1449).
  • Quadratic dependency lookups: getDependencies and getConsumers each run findIndex plus an edges filter, and the template calls them up to four times per card. Precompute a computed() map of id to deps and consumers once per graph (app/src/pages/signal-inspector.ts:498-504, :1637-1655).
  • Filter matches every resource: 'resource'.includes(q) makes queries such as e, so or our list all resources. Match the kind only on a prefix of at least 3 characters, or leave it to the kind chips (app/src/pages/signal-inspector.ts:1365).
  • Peeks only take environment injectors: toPeekRequest requires env, so inspect-signals tells agents to call pangular:highlight first, which moves the user's selection on the Signals page. Accept { id } or { selector } in SignalPeekRequest, reuse SignalTarget, and update the tool description (packages/devtools/src/signal-peek.ts:16-41, packages/devtools/src/devframe.ts:1976).
  • Live nodes not linked to source: the source-scan signals (file, line, component) only show when there is no live graph. Match live nodes to source entries by label and component class name, show file:line on the card, and show nothing when the match is ambiguous. Open in editor itself is tracked in phase 1 of 4: safe by default, open in editor and cheap shell wins #310 (app/src/pages/signal-inspector.ts:283-311).
  • linkedSignal writes may skip the hook: the history relies only on setPostSignalSetFn, and no test writes to a named linkedSignal. Add a real-Angular test that asserts a write entry; if it fails, hook linkedSignal writes another way or document the limit (packages/devtools/src/signal-history.ts:190-221, packages/devtools/src/__tests__/signal-history.test.ts) (to confirm).

Improvements

  • Restore a past value from the history list once signal editing (phase 2 of 4: match the official Angular DevTools #311) lands, as a one-click undo (app/src/pages/signal-inspector.ts, packages/devtools/src/signal-history.ts).
  • Show a JSON diff between consecutive history entries instead of the full value each time (app/src/pages/signal-inspector.ts).
  • Effect run counts and durations per effect node, if Angular exposes a hook, to spot runaway effects (packages/devtools/src/signal-graph.ts, app/src/pages/signal-inspector.ts).
  • Count unnamed signals in the inspect-signals answer, so agents can suggest adding debugName (packages/devtools/src/rpc/signal-tools.ts).

Already tracked elsewhere

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or shows wrong datafeatureA feature request or a pull request that adds one

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions