Skip to content

Performance regression in unicorn/no-instanceof-builtins and unicorn/explicit-length-check when eslint-plugin-better-tailwindcss is enabled #2842

@unktir

Description

@unktir

After adding eslint-plugin-better-tailwindcss to an existing eslint config based on @antfu/eslint-config, the unicorn plugin rules (notably unicorn/no-instanceof-builtins and in reproduction project usual config unicorn/explicit-length-check) show a huge increase in processing time when running ESLint. The slowdown appears only when better-tailwindcss is enabled. Removing it restores reasonable timings.

Before adding better-tailwindcss
> TIMING=1 pnpm eslint .

Rule                             | Time (ms) | Relative
:--------------------------------|----------:|--------:
format/prettier                  |   205.502 |    22.8%
unicorn/no-instanceof-builtins   |    90.976 |    10.1%
unused-imports/no-unused-imports |    61.712 |     6.9%
style/indent                     |    30.179 |     3.4%
ts/no-redeclare                  |    18.831 |     2.1%
perfectionist/sort-imports       |    16.346 |     1.8%
jsdoc/check-access               |    13.606 |     1.5%
unused-imports/no-unused-vars    |    11.791 |     1.3%
no-redeclare                     |     9.900 |     1.1%
vue/html-closing-bracket-newline |     9.506 |     1.1%
After adding
> TIMING=1 pnpm eslint .

Rule                                                | Time (ms) | Relative
:---------------------------------------------------|----------:|--------:
unicorn/no-instanceof-builtins                      | 59063.344 |    92.6%
better-tailwindcss/enforce-consistent-line-wrapping |  2506.707 |     3.9%
better-tailwindcss/no-unknown-classes               |  1238.458 |     1.9%
format/prettier                                     |   228.214 |     0.4%
unused-imports/no-unused-imports                    |    86.047 |     0.1%
style/indent                                        |    32.280 |     0.1%
better-tailwindcss/enforce-consistent-class-order   |    28.766 |     0.0%
jsdoc/check-access                                  |    16.785 |     0.0%
perfectionist/sort-imports                          |    16.455 |     0.0%
ts/no-redeclare                                     |    15.382 |     0.0%

In a minimal reproduction project I created (examples below):

Before adding better-tailwindcss
> TIMING=1 pnpm eslint .

Rule                                | Time (ms) | Relative
:-----------------------------------|----------:|--------:
unicorn/explicit-length-check       |    11.429 |    25.0%
vue/block-order                     |     1.565 |     3.4%
unicorn/prevent-abbreviations       |     1.497 |     3.3%
unicorn/expiring-todo-comments      |     0.992 |     2.2%
vue/html-indent                     |     0.989 |     2.2%
vue/no-ref-as-operand               |     0.773 |     1.7%
vue/html-closing-bracket-newline    |     0.695 |     1.5%
vue/no-async-in-computed-properties |     0.653 |     1.4%
unicorn/filename-case               |     0.609 |     1.3%
unicorn/import-style                |     0.598 |     1.3%
After adding
> TIMING=1 pnpm eslint .

Rule                                                | Time (ms) | Relative
:---------------------------------------------------|----------:|--------:
unicorn/explicit-length-check                       |   509.389 |    63.8%
better-tailwindcss/enforce-consistent-line-wrapping |   226.055 |    28.3%
better-tailwindcss/enforce-consistent-class-order   |    10.137 |     1.3%
unicorn/prevent-abbreviations                       |     1.877 |     0.2%
vue/block-order                                     |     1.653 |     0.2%
better-tailwindcss/enforce-canonical-classes        |     1.616 |     0.2%
better-tailwindcss/enforce-shorthand-classes        |     1.485 |     0.2%
better-tailwindcss/no-conflicting-classes           |     1.483 |     0.2%
better-tailwindcss/no-unknown-classes               |     1.273 |     0.2%
unicorn/expiring-todo-comments                      |     1.119 |     0.1%

At least the following rules are affected:

  • unicorn/no-instanceof-builtins
  • unicorn/explicit-length-check

Minimal reproduction steps (I can upload repo if you need):

package.json:

{
  "name": "test-app",
  "type": "module",
  "packageManager": "[email protected]",
  "devDependencies": {
    "@antfu/eslint-config": "^6.5.1",
    "eslint": "^9.39.1",
    "eslint-plugin-better-tailwindcss": "4.0.0-beta.6"
    "eslint-plugin-unicorn": "^62.0.0"
    "eslint-plugin-vue": "^10.6.2",
    "typescript": "~5.9.3",
    "vite": "^7.2.6",
    "vue": "^3.5.25"
  }
}

eslint.config.ts (antfu):

import antfu from '@antfu/eslint-config'
import tailwindcss from 'eslint-plugin-better-tailwindcss'

export default antfu(
  {
    ignores: ['**/dist/**'],
    stylistic: true,
    isInEditor: false,
    typescript: true,
    vue: true,
  },
  {
    plugins: {
      'better-tailwindcss': tailwindcss,
    },
    rules: {
      ...tailwindcss.configs['recommended-warn'].rules,
      ...tailwindcss.configs['recommended-error'].rules,
    },
  },
)

eslint.config.ts (usual):

import tailwindcss from 'eslint-plugin-better-tailwindcss'
import unicorn from 'eslint-plugin-unicorn'
import vue from 'eslint-plugin-vue'

export default [
  {
    ignores: ['**/dist/**'],
  },
  unicorn.configs.recommended,
  {
    rules: {
      'unicorn/no-instanceof-builtins': 'error',
    },
  },
  ...vue.configs['flat/recommended'],
  {
    plugins: {
      'better-tailwindcss': tailwindcss,
    },
    rules: {
      ...tailwindcss.configs['recommended-warn'].rules,
      ...tailwindcss.configs['recommended-error'].rules,
    },
  },
]

The observed rule(s) that slow down are from eslint-plugin-unicorn. The only change I made is enabling eslint-plugin-better-tailwindcss, which results in a dramatic time increase for unicorn rules (better-tailwindcss rules are slower too, but to a lesser extent). I am not certain where to file this, but because the unicorn plugin’s runtime increases, I am filing it here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions