Commit 530438e
authored
francoismassart#136: Speed up execution time with caches (francoismassart#143)
* francoismassart#136: Speed up `tailwindcss/enforces-shorthand`
Using chrome://inspect/, I found that the `patchRegex` function took a
lot of time to calculate. It looked like it was often called with the
same parameters, which I have optimized by adding a cache.
The cache uses a `WeakMap`, storing a plain string-to-string object for
every `config` object that is passed to `patchRegex`. I chose to use
`WeakMap` here because the Tailwind CSS config object may change over
time (see lib/util/customConfig.js), and this allows the garbage
collector to clean the cache when an old config is no longer used.
On my codebase (which I can't share, unfortunately), this greatly
reduces the run time of the `tailwindcss/enforces-shorthand` rule.
Details of the run time:
Command executed:
```
$ TIMING=1 node --inspect ./node_modules/.bin/eslint .
```
Before this commit:
```
Rule | Time (ms) | Relative
:----------------------------------------------|----------:|--------:
tailwindcss/enforces-shorthand | 2444.777 | 70.0%
tailwindcss/no-custom-classname | 487.850 | 14.0%
tailwindcss/no-contradicting-classname | 289.491 | 8.3%
tailwindcss/classnames-order | 229.961 | 6.6%
tailwindcss/migration-from-tailwind-2 | 20.250 | 0.6%
tailwindcss/enforces-negative-arbitrary-values | 17.669 | 0.5%
```
After this commit:
```
Rule | Time (ms) | Relative
:----------------------------------------------|----------:|--------:
tailwindcss/enforces-shorthand | 564.097 | 32.8%
tailwindcss/no-custom-classname | 531.374 | 30.9%
tailwindcss/no-contradicting-classname | 341.007 | 19.8%
tailwindcss/classnames-order | 238.749 | 13.9%
tailwindcss/enforces-negative-arbitrary-values | 22.539 | 1.3%
tailwindcss/migration-from-tailwind-2 | 20.349 | 1.2%
```
Note that the timings above are single runs, not averages, but repeated
runs show a similar pattern.
ESLint config used (which, for testing, I have adapted in such a way
that _only_ the `tailwindcss/*` rules are executed):
```
{
"env": {"browser": true, "es2020": true, "node": true},
"extends": ["plugin:tailwindcss/recommended"],
"overrides": [{"files": ["*.ts", "*.tsx"]}],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {"jsx": true},
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint"],
"settings": {
"react": {"version": "detect"},
"tailwindcss": {
"cssFiles": ["src/**/*.css"],
"officialSorting": true
}
}
}
```
* francoismassart#136: Speed up `tailwindcss/classnames-order` with `officialSorting: true`
Using chrome://inspect/, I found that the `createContext` function from
the Tailwind API took a lot of time to execute. It turned out that this
function was called more than only a few times, so I have optimized this
by adding a cache.
The cache uses a `WeakMap`, storing a `contextFallback` object for
every `config` object that is passed to `patchRegex`. I chose to use
`WeakMap` here because the Tailwind CSS config object may change over
time (see lib/util/customConfig.js), and this allows the garbage
collector to clean the cache when an old config is no longer used.
Interestingly enough, the time to execute the `create` function for an
ESLint rule is not included in the time reported by `TIMING=1`, as can
be seen in the details below. However, on my codebase (which I can't
share, unfortunately), this roughly halves the total runtime of the
`eslint .` command when using only `tailwindcss/*` rules.
Details of the run time:
Commands executed:
```
$ TIMING=1 node --inspect ./node_modules/.bin/eslint .
$ time node --inspect ./node_modules/.bin/eslint .
```
Before this commit:
```
Rule | Time (ms) | Relative
:----------------------------------------------|----------:|--------:
tailwindcss/no-custom-classname | 491.130 | 32.6%
tailwindcss/enforces-shorthand | 483.797 | 32.1%
tailwindcss/no-contradicting-classname | 293.046 | 19.4%
tailwindcss/classnames-order | 206.097 | 13.7%
tailwindcss/migration-from-tailwind-2 | 16.470 | 1.1%
tailwindcss/enforces-negative-arbitrary-values | 16.250 | 1.1%
```
After this commit:
```
Rule | Time (ms) | Relative
:----------------------------------------------|----------:|--------:
tailwindcss/no-custom-classname | 482.266 | 34.0%
tailwindcss/enforces-shorthand | 434.553 | 30.6%
tailwindcss/no-contradicting-classname | 276.010 | 19.5%
tailwindcss/classnames-order | 180.044 | 12.7%
tailwindcss/migration-from-tailwind-2 | 24.113 | 1.7%
tailwindcss/enforces-negative-arbitrary-values | 20.486 | 1.4%
```
Note that the timings above are single runs, not averages.
Repeated runs show that the _reported_ time for `classnames-order` does
not change significantly.
However, the output of `time` shows a different picture:
before this commit, the `wall` time is 19s and the `user` time is 30s;
after this commit, the `wall` time is 10s and the `user` time is 17s.
These timings are averaged over 5 runs.
ESLint config used (which, for testing, I have adapted in such a way
that _only_ the `tailwindcss/*` rules are executed):
```
{
"env": {"browser": true, "es2020": true, "node": true},
"extends": ["plugin:tailwindcss/recommended"],
"overrides": [{"files": ["*.ts", "*.tsx"]}],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {"jsx": true},
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint"],
"settings": {
"react": {"version": "detect"},
"tailwindcss": {
"cssFiles": ["src/**/*.css"],
"officialSorting": true
}
}
}
```1 parent f44f72f commit 530438e
2 files changed
+22
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
25 | 27 | | |
26 | 28 | | |
27 | 29 | | |
| |||
88 | 90 | | |
89 | 91 | | |
90 | 92 | | |
91 | | - | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
92 | 101 | | |
93 | 102 | | |
94 | 103 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
261 | 261 | | |
262 | 262 | | |
263 | 263 | | |
| 264 | + | |
| 265 | + | |
264 | 266 | | |
265 | 267 | | |
266 | 268 | | |
267 | 269 | | |
268 | 270 | | |
269 | | - | |
| 271 | + | |
270 | 272 | | |
271 | 273 | | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
272 | 281 | | |
273 | 282 | | |
274 | 283 | | |
| |||
281 | 290 | | |
282 | 291 | | |
283 | 292 | | |
284 | | - | |
| 293 | + | |
285 | 294 | | |
286 | 295 | | |
287 | 296 | | |
| |||
336 | 345 | | |
337 | 346 | | |
338 | 347 | | |
339 | | - | |
| 348 | + | |
340 | 349 | | |
341 | 350 | | |
342 | 351 | | |
| |||
0 commit comments