eslint-plugin-import: `import/namespace` is very slow
In our medium-sized mixed JS/TS codebase, specifically disabling import/namespace
significantly reduced our lint times. I haven’t found this mentioned by anyone else, so I wanted to share the finding, because it was very surprising.
Our prior configuration ran like this:
Rule | Time (ms) | Relative
:---------------------------------|----------:|--------:
import/namespace | 5762.140 | 64.7%
import/no-relative-packages | 673.212 | 7.6%
import/named | 471.116 | 5.3%
import/no-extraneous-dependencies | 317.690 | 3.6%
import/extensions | 254.717 | 2.9%
Done in 14.53s.
I always assumed this was just the “first rule tax” while the export map is created, but adding "import/namespace": "off"
did this for us:
Rule | Time (ms) | Relative
:---------------------------------|----------:|--------:
import/named | 1459.028 | 33.6%
import/no-relative-packages | 577.911 | 13.3%
import/no-duplicates | 408.152 | 9.4%
import/extensions | 401.591 | 9.2%
import/no-extraneous-dependencies | 276.880 | 6.4%
Done in 9.44s.
Given we already use "import/no-namespace": "error"
, this rule wasn’t doing anything for us anyway. With one line we’ve managed to significantly improve IDE responsiveness.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 17
- Comments: 25 (12 by maintainers)
Links to this issue
Commits related to this issue
- [Refactor] `namespace`: try to improve performance See #2340 — committed to ljharb/eslint-plugin-import by ljharb 2 years ago
- Update dependency eslint-plugin-import to v2.26.0 (#1284) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [eslint-plugin-import](https://github.com/i... — committed to Calciumdibromid/CaBr2 by deleted user 2 years ago
- Disable slow import/namespace rule - https://github.com/import-js/eslint-plugin-import/issues/2340 — committed to darekkay/darekkay-eslint-config by darekkay 2 years ago
- Add `import/extensions` setting to `.eslintrc.js` Required according to this issue comment: https://github.com/import-js/eslint-plugin-import/issues/2340#issuecomment-1105455308 — committed to motifland/markprompt-js by nickrttn a year ago
Indeed, it’s not necessarily that that rule is slow - it’s that whichever rule is the first one to build up an ExportsMap of your entire codebase will be slow. Not every rule uses it.
However,
named
does use the ExportsMap, so something strange must be going on with the namespace rule. I’d be happy to review a PR that improved its performance.Another data point here:
without namespace:
with namespace:
eslint-plugin-import@2.25.4, eslint@7.32.0, node@14.18.0
Yes, that’d be great. It especially must be set if you’re using “not standard javascript”, namely, TS.
Throwing some timing blocks around the visitors, it spends ~40% of the time in Program and ~60% in MemberExpression.
@the-ult Make sure to compare total time with vs. without the rule, so you can rule out the building of the export map as the cause. It would be good to have another solid data point here!
hmm, maybe! I have no idea how eslint decides to order the rules.
What’s probably easiest is to run timings; then disable the slowest rule and run them again, and in theory all but two should be roughly the same - and the one that’s massively bigger in each run would be the one containing the export map buildup.
See https://github.com/import-js/eslint-plugin-import/issues/2340#issuecomment-1002398962; whichever is the first rule to build the ExportMap will be the slowest.
With import/order enabled in
eslint.json
20secwithout: 13sec
For a simple (small library)
I’m getting similar results on an angular-eslint project:
As you can see, the top 3 rules are from this plugin.
Seems like no dice, unfortunately. No apparent improvement from putting that snippet into Program 😦
Same in our project. Seems to be really slow:
Rules: