Skip to content

perf(plugin): early-exit sweep — cheap discriminators before expensive walks - #1047

Merged
rayhanadev merged 1 commit into
mainfrom
ray/perf-sweep-early-exit
Jul 3, 2026
Merged

perf(plugin): early-exit sweep — cheap discriminators before expensive walks#1047
rayhanadev merged 1 commit into
mainfrom
ray/perf-sweep-early-exit

Conversation

@rayhanadev

@rayhanadev rayhanadev commented Jul 3, 2026

Copy link
Copy Markdown
Member

Why

The multi-agent perf audit's largest cross-cutting theme: ~24 rules ran subtree walks, scope traces, parent climbs, or settings parses before a trivial name/type/substring check that usually fails. This sweep reorders them and adds whole-file no-op gates where a Program-level fact (no zod import, no recycler-list import, no JSX) makes the rule inert. Findings: #6 #11 #18 #19 #42 #56 #100 #121 #129 #193 #205 #206 #217 #236 #237 #238 #259 #299 #308(partial) #327 #385 #386 #387 #428.

Before / After: pure predicate reorders and gates — the reported diagnostic set is provably unchanged (every gate is an ANDed condition of the existing report path).

What changed

  • a11y: raw-name bails before getElementType/generated-image climbs (alt-text, anchor-is-valid, img-redundant-alt, interactive-supports-focus, role-supports-aria-props) via a new has-jsx-a11y-settings util (safe: without settings the alias sets are empty).
  • Whole-file gates: zod rules on a literal "zod" import (the detectors cannot fire without one — verified), react-native list rules on recycler package imports, rn-no-raw-text on JSX presence, nextjs-no-side-effect-in-get-handler on filename at Program.
  • security-scan insecure-crypto-risk: trigger-token pre-filter over raw content (conservative: the stripper only blanks characters, so stripped-content tokens are always present raw).
  • Assorted: render-name pattern before scope traces (no-render-in-render), value-shape checks before parent climbs (prefer-stable-empty-fallback), charCodeAt uppercase check + hoisted Set (no-unstable-nested-components), first-match early exits (containsFetchCall, is-create-element-call).
  • Deliberately NOT done (finding overreach, catalog annotated): fix(effect-needs-cleanup): recognize AbortController.abort() as a valid cleanup #308's whole-file react-import gate would drop real diagnostics on global-React files — only the safe single-lookup half shipped.

Test plan

  • Plugin suite: 8704 pass / 94 skip — zero deltas vs pristine main. Root typecheck + lint clean.
  • Equivalence: 617-file corpus scan before/after — 291 diagnostics, sorted tuples byte-identical.
  • Adversarial review: an independent reviewer attacked every reorder and gate (side effects, message-choice changes, gate-excluded firing paths) — no divergence found.

Note: touches interactive-supports-focus.ts and rn-no-raw-text.ts, which the set-membership sweep PR also touches — whichever merges second needs a trivial rebase.

🤖 Generated with Claude Code


Note

Low Risk
Changes are predicate reordering and conservative skip gates only; PR claims byte-identical corpus diagnostics, so behavioral risk is low aside from any missed edge case in gate logic.

Overview
Performance-only refactor across ~23 oxlint rules: cheap checks and whole-file gates run before AST walks, scope lookups, settings parsing, and regex-heavy className work. Reported diagnostics are intended to stay identical (gates are conservative AND conditions on existing report paths).

Whole-file gates at Program: Zod v4 rules skip files without a "zod" import; FlashList/LegendList rules skip without recycler package imports (RECYCLABLE_LIST_PACKAGE_SOURCES); rn-no-raw-text skips wrapper classification when the file has no JSX; nextjs-no-side-effect-in-get-handler hoists route filename checks once per file.

a11y: New hasJsxA11ySettings lets alt-text and anchor-is-valid bail on raw JSX tag names before getElementType. Other a11y rules reorder checks (e.g. role-supports-aria-props collects aria-* first; interactive-supports-focus requires role + handlers earlier).

Misc: Tailwind design rules add substring guards before regex; insecure-crypto-risk pre-filters raw content; containsFetchCall and is-create-element-call stop after first match; assorted predicate reordering (no-render-in-render, js-hoist-intl, prefer-stable-empty-fallback, no-unstable-nested-components, server-cache-with-object-literal, no-create-context-in-render import helpers).

Reviewed by Cursor Bugbot for commit 4f82a61. Bugbot is set up for automated code reviews on this repo. Configure here.

…e walks

Reorders ~23 rules/utils so trivial name/type/substring checks run before
subtree walks, scope traces, parent climbs, and settings parses; adds
whole-file no-op gates (zod import gate, recycler-package import gate,
JSX-presence gate for rn-no-raw-text, crypto-token gate for
insecure-crypto-risk) and prunes containsFetchCall after the first match.
Findings #6 #11 #18 #19 #42 #56 #100 #121 #129 #193 #205 #206 #217 #236-#238
#259 #299 #308 #327 #385-#387 #428 from the perf audit catalog; behavior
verified identical via the 291-diagnostic equivalence corpus.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 3, 2026 22:24

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@pkg-pr-new

pkg-pr-new Bot commented Jul 3, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/eslint-plugin-react-doctor@1047
npm i https://pkg.pr.new/oxlint-plugin-react-doctor@1047
npm i https://pkg.pr.new/react-doctor@1047

commit: 4f82a61

@rayhanadev
rayhanadev merged commit fa61c20 into main Jul 3, 2026
24 of 26 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 3, 2026
@rayhanadev
rayhanadev deleted the ray/perf-sweep-early-exit branch July 3, 2026 23:22
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