Skip to content

Forensic render-issue audit (post §4 / §16) — report only, no code changes#321

Closed
Copilot wants to merge 1 commit into
v2.0-devfrom
copilot/forensic-react-render-issue-analysis
Closed

Forensic render-issue audit (post §4 / §16) — report only, no code changes#321
Copilot wants to merge 1 commit into
v2.0-devfrom
copilot/forensic-react-render-issue-analysis

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jun 4, 2026

Static survey of the post-§4 / §16 codebase against the 10 anti-patterns in the issue. No code changes; per the issue instructions this PR is the report.

Summary

Codebase is largely clean. The §16 discipline (refs-to-latest, useSyncExternalStore selectors, version-keyed broadcast, EMPTY_* sentinels) is applied consistently. One real cleanup hazard and one edge-case timer found; everything else flagged by a casual scan is intentional and documented in PERF-ARCHITECTURE.md.

HIGH — likely real bug

  • showError schedules an uncancelled setTimeoutsrc/hooks/useCommon.ts:78–84
    • No handle stored; firing after unmount → "setState on unmounted component" in dev.
    • Repeated errors during the window stack timers and clobber display order.
    const showError = (errorString: ErrorString) => {
      if (showErrorMessages) {
        setError(errorString)
        setTimeout(() => setError(null), errorDisplayTime) // ← no cancellation
      }
      console.warn('Error', errorString)
    }
    • Pin-first test: jest.useFakeTimers(), fire two errors, assert getTimerCount() === 2 (current) → fix → flip to === 1. Plus: error → unmount → runAllTimers() → assert no React warning.

MEDIUM — worth pinning behaviourally

  • Inline 10 ms setTimeout on <input onFocus>src/ValueNodes.tsx:225
    • Survives most cases; under Strict Mode / concurrent transitions / fast Tab during search-filter churn the input can unmount before fire → .select() on a detached node.
    • Test: userEvent.tab() across N number inputs while toggling filter; no errors, no leftover timers post-blur.

LOW / intentional (do not touch)

  • useKeyboardListener re-attach pattern — balanced add/remove, ref-to-latest absorbs identity churn (ValueNodes.tsx:295–350).
  • useAppliedBroadcast deps [version, commands] — deliberate, documented (CollapseProvider.tsx:221–248).
  • Inline () => setX(...) callbacks on non-memo'd leaves (StringDisplay, raw <input>, EditButtons) — no memoisation defeated.
  • All Provider value={...} sites are stable: EditingProvider uses storeRef.current; CollapseProvider, ThemeProvider, DragSourceProvider are useMemo'd; JsonEditor defaults via module-scoped EMPTY_* constants.
  • useState lazy-init audit clean. No index-based keys in mutable hot-path lists. useEditingSelector constrains return to primitive.

Cleanup hazards

File:line Resource Cleanup Severity
src/hooks/useCommon.ts:81 setTimeout No Medium (real)
src/ValueNodes.tsx:225 setTimeout No Low (edge)
src/JsonEditor.tsx:170–182 setTimeout (search debounce) Yes
src/ValueNodes.tsx:320–327 setTimeout + addEventListener Yes

No setInterval / MutationObserver / ResizeObserver / IntersectionObserver usage in src/ — nothing to leak in those categories.

Recommended next steps

  1. Profiler + fake-timer regression test pinning the broken showError behaviour, then fix in a follow-up PR.
  2. Lightweight test for the NumberValue focus-timeout edge case; fix opportunistically when the file is next touched.
  3. No action on L-tier items; consider a one-line comment near showError once fixed, referencing the cancellation requirement.

Out of scope (per the issue): large-fixture wall-clock benchmarks.

Copilot AI linked an issue Jun 4, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Run forensic analysis for React rendering issues Forensic render-issue audit (post §4 / §16) — report only, no code changes Jun 4, 2026
Copilot AI requested a review from CarlosNZ June 4, 2026 01:48
@CarlosNZ
Copy link
Copy Markdown
Owner

CarlosNZ commented Jun 8, 2026

Out of date after #330

@CarlosNZ CarlosNZ closed this Jun 8, 2026
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.

Forensic React render-issue analysis (post §4 / §16)

2 participants