Skip to content

perf(linter): only run react-perf rules on JSX attribute nodes#24083

Merged
graphite-app[bot] merged 1 commit into
mainfrom
07-02-perf_linter_only_run_react-perf_rules_on_jsx_attribute_nodes
Jul 2, 2026
Merged

perf(linter): only run react-perf rules on JSX attribute nodes#24083
graphite-app[bot] merged 1 commit into
mainfrom
07-02-perf_linter_only_run_react-perf_rules_on_jsx_attribute_nodes

Conversation

@camchenry

@camchenry camchenry commented Jul 2, 2026

Copy link
Copy Markdown
Member

Now that the react perf rules are not a special kind of lint rule, all we need to do is pull out the main node type check in order to opt-in to the AST node type optimizations in the linter codegen. In this case, the node type check is enforced by having the shared function accept the JSXAttribute instead of the AstNode, so it's impossible to not check the AST node type in the run function first.

This improves performance by then allowing the linter runtime to skip these rules completely for files that don't contain any JSX attributes.

camchenry commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions github-actions Bot added the A-linter Area - Linter label Jul 2, 2026
@graphite-app
graphite-app Bot changed the base branch from 07-02-refactor_linter_remove_custom_react_perf_lint_rule_trait to graphite-base/24083 July 2, 2026 17:18
@camchenry
camchenry marked this pull request as ready for review July 2, 2026 17:19
@camchenry
camchenry requested a review from camc314 as a code owner July 2, 2026 17:19
@codspeed-hq

codspeed-hq Bot commented Jul 2, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 4.92%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
✅ 3 untouched benchmarks
⏩ 66 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation linter[kitchen-sink.tsx] 173 ms 162.8 ms +6.28%
Simulation linter[App.tsx] 105.6 ms 102 ms +3.59%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing 07-02-perf_linter_only_run_react-perf_rules_on_jsx_attribute_nodes (4348bcd) with main (002ab35)2

Open in CodSpeed

Footnotes

  1. 66 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on graphite-base/24083 (bc94678) during the generation of this report, so main (002ab35) was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@camchenry camchenry added the 0-merge Merge with Graphite Merge Queue label Jul 2, 2026

camchenry commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

Merge activity

  • Jul 2, 5:22 PM UTC: The merge label '0-merge' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Jul 2, 5:22 PM UTC: camchenry added this pull request to the Graphite merge queue.
  • Jul 2, 5:23 PM UTC: The Graphite merge queue removed this pull request due to downstack failures on PR #24082.
  • Jul 2, 5:23 PM UTC: The Graphite merge queue removed this pull request due to downstack failures on PR #24082.
  • Jul 2, 5:37 PM UTC: The merge label '0-merge' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Jul 2, 5:38 PM UTC: camc314 added this pull request to the Graphite merge queue.
  • Jul 2, 5:40 PM UTC: The Graphite merge queue couldn't merge this PR because it had merge conflicts.
  • Jul 2, 5:50 PM UTC: The merge label '0-merge' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Jul 2, 5:50 PM UTC: camchenry added this pull request to the Graphite merge queue.
  • Jul 2, 5:56 PM UTC: Merged by the Graphite merge queue.

@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Jul 2, 2026
@camc314 camc314 self-assigned this Jul 2, 2026
@camc314 camc314 added the 0-merge Merge with Graphite Merge Queue label Jul 2, 2026
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Jul 2, 2026
@graphite-app
graphite-app Bot changed the base branch from graphite-base/24083 to main July 2, 2026 17:39
@camchenry
camchenry force-pushed the 07-02-perf_linter_only_run_react-perf_rules_on_jsx_attribute_nodes branch from 4348bcd to 2936968 Compare July 2, 2026 17:44
@camchenry camchenry added the 0-merge Merge with Graphite Merge Queue label Jul 2, 2026
Now that the react perf rules are not a special kind of lint rule, all we need to do is pull out the main node type check in order to opt-in to the AST node type optimizations in the linter codegen. In this case, the node type check is enforced by having the shared function accept the `JSXAttribute` instead of the `AstNode`, so it's impossible to _not_ check the AST node type in the `run` function first.

This improves performance by then allowing the linter runtime to skip these rules completely for files that don't contain any JSX attributes.
@graphite-app
graphite-app Bot force-pushed the 07-02-perf_linter_only_run_react-perf_rules_on_jsx_attribute_nodes branch from 2936968 to bca7ce5 Compare July 2, 2026 17:51
@graphite-app
graphite-app Bot merged commit bca7ce5 into main Jul 2, 2026
29 checks passed
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Jul 2, 2026
@graphite-app
graphite-app Bot deleted the 07-02-perf_linter_only_run_react-perf_rules_on_jsx_attribute_nodes branch July 2, 2026 17:56
camc314 pushed a commit that referenced this pull request Jul 3, 2026
Now that the react perf rules are not a special kind of lint rule, all we need to do is pull out the main node type check in order to opt-in to the AST node type optimizations in the linter codegen. In this case, the node type check is enforced by having the shared function accept the `JSXAttribute` instead of the `AstNode`, so it's impossible to _not_ check the AST node type in the `run` function first.

This improves performance by then allowing the linter runtime to skip these rules completely for files that don't contain any JSX attributes.
camc314 pushed a commit that referenced this pull request Jul 3, 2026
Now that the react perf rules are not a special kind of lint rule, all we need to do is pull out the main node type check in order to opt-in to the AST node type optimizations in the linter codegen. In this case, the node type check is enforced by having the shared function accept the `JSXAttribute` instead of the `AstNode`, so it's impossible to _not_ check the AST node type in the `run` function first.

This improves performance by then allowing the linter runtime to skip these rules completely for files that don't contain any JSX attributes.
Boshen added a commit that referenced this pull request Jul 6, 2026
# Oxlint
### 🚀 Features

- 7db7a29 allocator: Add `ReplaceWith` trait (#24012) (overlookmotel)
- a2c97f3 linter/unicorn: Implement `explicit-timer-delay` rule (#23612)
(Mikhail Baev)
- 85735cb linter/unicorn: Implement `no-confusing-array-with` rule
(#23638) (Shekhu☺️)
- cb4fbb9 linter/eslint: Implement no-unreachable-loop rule (#23975)
(Todor Andonov)
- dc32112 linter/eslint/no-constant-binary-expression: Check relational
comparisons (#24088) (camc314)
- 439c344 linter/jsdoc: Added missing options to `jsdoc/require-param`
rule (#23364) (kapobajza)
- 62af717 linter/unicorn/filename-case: Add `lowercase` and
`screamingSnakeCase` (#24045) (Boshen)
- d963967 linter/unicorn/no-array-sort: Add `allowAfterSpread` option
(#24043) (Boshen)
- 0a75682 linter: Add per-rule timings for type-aware linting (#22488)
(camchenry)
- 743e222 linter/react: Add `disallowedValues` option for
`forbid-dom-props` rule (#23970) (Mikhail Baev)

### 🐛 Bug Fixes

- 7b80010 linter: Use direct binding symbol ids (#24216) (camc314)
- 8f94b49 linter/import/no-duplicates: Don't flag a type-only import
beside a side-effect import (#24030) (Boshen)
- d8c3fee linter/react/rules-of-hooks: Flag `useEffectEvent` escapes
(#23764) (Rayan Salhab)
- 0a7312b linter/no-deprecated-functions: Map `require.requireActual` to
`jest.requireActual` (#23627) (Jerry Zhao)
- d9e3ab3 linter/eslint/no-useless-return: Handle switch case
continuation (#23984) (camc314)
- 0b25582 ast: Type binding node `typeAnnotation` as `TSTypeAnnotation |
null` (#23113) (Boshen)
- 122d112 linter/eslint/no-restricted-imports: Flag dynamic import()
expressions (#24029) (Boshen)
- 59b6b83 linter: Avoid `OnceLock` re-entry on cyclic `export *`
re-exports (#23632) (Jerry Zhao)
- dd09af0 linter/import/namespace: Avoid panic on destructuring of an
unresolvable namespace re-export (#23626) (Jerry Zhao)
- bdb51c7 linter/jest/prefer-ending-with-an-expect: Validate config
patterns (#24122) (camc314)
- e383843 linter/unicorn/prefer-modern-dom-apis: Skip fixer for non
identifier arguments (#23630) (Jerry Zhao)
- 0ac4c83 linter: Detect circular config extends (#24115) (camc314)
- bae1edf linter/import/namespace: Check namespace imports after named
imports (#24094) (camc314)
- cd8fdfe linter/eslint/no-eval: Recognize Array.from family thisArg
(#24091) (camc314)
- 851ee43 linter/eslint/no-eval: Resolve this binding for functions
returned from an IIFE (#23643) (Jerry Zhao)
- 002ab35 linter/unicorn: Avoid prefer-array-find rest destructuring
false positive (#23654) (ColemanDunn)
- 01c8775 linter/unicorn/filename-case: Keep digits attached in
screamingSnakeCase (#24056) (Boshen)
- f256941 linter: Recognize `@effect/vitest` as a vitest import source
(#24025) (Boshen)
- 73eeb1d linter/import/extensions: Honor per-extension `never` for
explicit extensions (#24031) (Boshen)
- d4ebe1f linter: Reject non-object oxlint config files (#24026)
(Boshen)
- 45d607d linter/react/forbid-component-props: Make allow/disallow lists
optional in schema (#24024) (Boshen)
- 54076ad linter/unicorn/no-array-for-each: Suggest entries loop for
index callbacks (#24004) (camc314)
- d057736 linter/jsdoc: Avoid param root underflow (#23945) (camc314)
- 29c76bf linter/unicorn/prefer-at: Skip object numeric-key access
(#23909) (Gaurav Dubey)

### ⚡ Performance

- 657a8fc linter/oxc/bad-array-method-on-arguments: Only run on member
expressions instead of all identifiers (#24164) (camchenry)
- 073d9e7 linter/eslint/prefer-rest-params: Run on functions instead of
all identifiers (#24163) (camchenry)
- e5a4162 linter/jest/no-confusing-set-timeout: Early exit fast path
(#24092) (camc314)
- bca7ce5 linter: Only run react-perf rules on JSX attribute nodes
(#24083) (camchenry)
- 6881bf6 linter: Compute `apply_overrides` rule set lazily (#23648)
(Jerry Zhao)
- 911c106 linter/eslint/no-obj-calls: Use resolved reference instead of
scope walk (#23895) (Marius Schulz)
- dc8fd9a linter/unicorn/prefer-dom-node-text-content: Change dispatch
to run only on less common node types (#23897) (Connor Shea)
- fdbd34d linter/eslint/no-useless-call: Fast-path static callees
(#24077) (camc314)
- b1be114 linter/import/extensions: Skip empty config and borrow
extensions (#24075) (camc314)
- 4781b2d linter/eslint/no-obj-calls: Use direct global matches (#24076)
(camc314)
- e6cee89 linter: Avoid node-chain allocation for non-Jest calls
(#23907) (Yagiz Nizipli)
- 30dc517 linter/typescript/no-restricted-types: O(1) banned-type
lookups (#23827) (Yagiz Nizipli)

### 📚 Documentation

- 6ca9125 linter/typescript: Clarify consistent-type-imports behavior
(#23972) (camc314)
# Oxfmt
### 🚀 Features

- 4f4313e formatter_css: Update oxc-css-parser 0.0.5 (#24120) (leaysgur)
- 0ccd8a1 formatter_graphql: Update oxc-graphql-parser 0.0.5 (#24106)
(leaysgur)
- 89ec3d9 formatter_core: Add literal line and root indention primitives
(#24051) (leaysgur)
- 213a96b formatter_core: Add no-expand-parent for multiline text
(#24050) (leaysgur)
- 0e5bcc9 formatter_graphql: Update oxc-graphql-parser 0.0.4 (#24039)
(leaysgur)
- e0b35a1 formatter_css: Update `[email protected]` (#23974)
(leaysgur)

### 🐛 Bug Fixes

- 1fe6546 formatter: Omit unneeded `;` for type members with `no-semi`
(#24212) (leaysgur)
- 0ad7316 formatter: Print space for `ForStatement`.`update` only if
exists (#24211) (leaysgur)
- 3abbed5 formatter: Print `;` before jsdoc type-cast parens with
no-semi (#24208) (leaysgur)
- 9af3833 formatter_css: Make scss formatter consistent (#24207)
(leaysgur)
- 46d7194 formatter_css: Use fill IR for `@forward` members (#24206)
(leaysgur)
- e31038f formatter_css: Keep comment inside sass config list (#24205)
(leaysgur)
- d3b9591 formatter: Add parens around `await/yield` with `<T>` (#24202)
(leaysgur)
- 2121a55 oxfmt: Reuse tinypool process during the same LSP process
(#24197) (leaysgur)
- 9bf4b4a formatter_css: Align CSS output to Prettier 3.9.1 (#24100)
(leaysgur)
- cd2452e formatter_css: Align SCSS output to Prettier 3.9.1 (#24097)
(leaysgur)
- 4ee8745 formatter_css: Keep selector value contain line-break without
breaking line (#24055) (leaysgur)
- e1ece97 formatter_graphql: Break `implements` list by print-width
(#23997) (leaysgur)
- 0a6b16c formatter_json: Preserve key and literal value for
json-stringify (#23996) (leaysgur)
- 903ab6e formatter_css: Preserve newlines in css-in-js selector list
(#23992) (leaysgur)
- ea5d095 oxfmt: Update `--migrate prettier` (#23963) (leaysgur)

### ⚡ Performance

- 468e1e3 formatter_core: Make printer queues cursor-based (#24098)
(Boshen)
- c59f2fe rust: Return impl ExactSizeIterator from slice-backed
accessors (#24144) (Boshen)
- c292fb2 formatter: Inline fits element dispatcher (#23982) (camc314)

Co-authored-by: Boshen <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-linter Area - Linter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants