Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

state-snapshot-rule is surprisingly expensive #57

Open
kirbysayshi opened this issue Mar 10, 2025 · 3 comments · May be fixed by #58
Open

state-snapshot-rule is surprisingly expensive #57

kirbysayshi opened this issue Mar 10, 2025 · 3 comments · May be fixed by #58
Labels
help wanted Extra attention is needed

Comments

@kirbysayshi
Copy link

Hello there!

I did some brief profiling with eslint, and found that a significant time spent linting our codebase was due to the state-snapshot-rule. Here is a single file example (note: the file has about 1300 lines of code):

time TIMING=1 pnpm exec eslint REDACTED-PATH/Playground.tsx
REDACTED-PATH/Playground.tsx
  394:9  warning  Better to just use proxy state  valtio/state-snapshot-rule
  422:5  warning  Better to just use proxy state  valtio/state-snapshot-rule

✖ 2 problems (0 errors, 2 warnings)

Rule                                    | Time (ms) | Relative
:---------------------------------------|----------:|--------:
valtio/state-snapshot-rule              |    51.368 |    32.2%
react/jsx-no-constructed-context-values |    15.081 |     9.5%
simple-import-sort/imports              |    10.509 |     6.6%
react/no-direct-mutation-state          |    10.086 |     6.3%
react/no-danger-with-children           |     7.334 |     4.6%
react/no-typos                          |     6.383 |     4.0%
react/require-render-return             |     6.233 |     3.9%
@typescript-eslint/naming-convention    |     4.980 |     3.1%
react-hooks/exhaustive-deps             |     3.521 |     2.2%
react/jsx-uses-react                    |     2.264 |     1.4%
TIMING=1 pnpm exec eslint REDACTED-PATH/Playground.tsx  21.42s user 4.65s system 123% cpu 21.173 total

As you can see, a single file takes 21s with the rule enabled. If I disable the rule, the entire file only takes ~15s:

Rule                                    | Time (ms) | Relative
:---------------------------------------|----------:|--------:
react/jsx-no-constructed-context-values |    14.836 |    14.1%
react/no-direct-mutation-state          |    10.372 |     9.9%
simple-import-sort/imports              |     9.364 |     8.9%
@typescript-eslint/ban-types            |     7.336 |     7.0%
react/no-typos                          |     6.632 |     6.3%
react/require-render-return             |     6.350 |     6.0%
@typescript-eslint/naming-convention    |     4.311 |     4.1%
react-hooks/exhaustive-deps             |     3.657 |     3.5%
@typescript-eslint/no-empty-function    |     2.524 |     2.4%
@typescript-eslint/no-redeclare         |     2.368 |     2.3%
TIMING=1 pnpm exec eslint REDACTED-PATH/Playground.tsx  19.59s user 3.13s system 150% cpu 15.055 total

When multiplied across the codebase, the difference in timing is more noticeable. Before:

$ time TIMING=1 pnpm exec eslint .
Rule                                    | Time (ms) | Relative
:---------------------------------------|----------:|--------:
valtio/state-snapshot-rule              | 13505.425 |    40.9%
@typescript-eslint/no-redeclare         |  3328.420 |    10.1%
react/no-direct-mutation-state          |  2335.941 |     7.1%
react/jsx-no-constructed-context-values |  1800.343 |     5.5%
react/require-render-return             |  1382.010 |     4.2%
react/no-typos                          |  1095.258 |     3.3%
@typescript-eslint/naming-convention    |  1068.797 |     3.2%
simple-import-sort/imports              |  1017.479 |     3.1%
react/jsx-uses-react                    |   774.067 |     2.3%
jsx-a11y/role-supports-aria-props       |   476.845 |     1.4%
TIMING=1 pnpm exec eslint .  132.84s user 18.88s system 137% cpu 1:50.64 total

After disabling:

Rule                                    | Time (ms) | Relative
:---------------------------------------|----------:|--------:
@typescript-eslint/no-redeclare         |  3150.915 |    17.4%
react/no-direct-mutation-state          |  1993.336 |    11.0%
react/jsx-no-constructed-context-values |  1739.310 |     9.6%
react/require-render-return             |  1129.678 |     6.2%
simple-import-sort/imports              |   972.616 |     5.4%
react/no-typos                          |   971.512 |     5.4%
@typescript-eslint/naming-convention    |   968.518 |     5.4%
react/jsx-uses-react                    |   916.780 |     5.1%
jsx-a11y/role-supports-aria-props       |   487.564 |     2.7%
no-restricted-imports                   |   428.382 |     2.4%
TIMING=1 pnpm exec eslint .  119.53s user 15.31s system 143% cpu 1:33.98 total

So, a 20% speedup after disabling this rule. Note that this is using eslint v7 (we're out of date), but I have also tried using v9 during an upgrade attempt and found very similar results. There is a chance this is something extremely specific to our codebase's use of types, but it's unclear to me how only state-snapshot-rule would be affected by that.

I apologize for not doing a deeper investigation, such as profiling/flamecharts, and just reporting! But I figured it was worth relaying our experience in case there was something obvious either we're doing wrong or that can be done to improve the performance of the rule. For now, we're going to disable the rule because it tends to also have false positives, which have reduced our developers' confidence (e.g. most most everyone was ignoring it! 🙃). Regardless, thank you for making this rule because it helped everyone learn 🚀

@dai-shi dai-shi added the help wanted Extra attention is needed label Mar 11, 2025
@barelyhuman
Copy link
Collaborator

Thanks for the profile, honestly that’s on me for not spending time profiling the rule for quite sometime.

We’ll look into making it faster if it’s being used in larger codebases

@kirbysayshi
Copy link
Author

Thank you! If you'd like me to test a beta version I can!

@kirbysayshi
Copy link
Author

honestly that’s on me for not spending time profiling the rule for quite sometime.

No need to cast blame! We're all busy and this code is FOSS: no expectations :D

@barelyhuman barelyhuman linked a pull request Mar 13, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants