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

Plugin's unbearably slow #160

Open
Faithfinder opened this issue Oct 7, 2024 · 7 comments
Open

Plugin's unbearably slow #160

Faithfinder opened this issue Oct 7, 2024 · 7 comments

Comments

@Faithfinder
Copy link

Here's the result of running linter with TIMING=1 on our codebase with panda recommended ruleset enabled

Rule                                            |  Time (ms) | Relative
:-----------------------------------------------|-----------:|--------:
@pandacss/no-invalid-token-paths                | 218124.183 |    27.8%
@pandacss/no-hardcoded-color                    | 167018.338 |    21.3%
@pandacss/no-unsafe-token-fn-usage              | 161571.479 |    20.6%
@pandacss/no-property-renaming                  | 126184.392 |    16.1%
@pandacss/no-dynamic-styling                    |  98082.907 |    12.5%
@typescript-eslint/no-confusing-void-expression |   2837.370 |     0.4%
@pandacss/file-not-included                     |   2297.380 |     0.3%
@typescript-eslint/no-misused-promises          |   1660.920 |     0.2%
@typescript-eslint/no-unused-vars               |   1032.843 |     0.1%
react/no-direct-mutation-state                  |    890.197 |     0.1%

Here's without, for comparison:

Rule                                            | Time (ms) | Relative
:-----------------------------------------------|----------:|--------:
@typescript-eslint/no-confusing-void-expression |  2371.804 |    29.4%
@typescript-eslint/no-misused-promises          |  1178.439 |    14.6%
@typescript-eslint/promise-function-async       |   673.703 |     8.4%
@typescript-eslint/no-unused-vars               |   634.428 |     7.9%
react/no-direct-mutation-state                  |   562.129 |     7.0%
react/prefer-stateless-function                 |   348.301 |     4.3%
react/require-render-return                     |   294.588 |     3.7%
no-redeclare                                    |   256.820 |     3.2%
react/no-unknown-property                       |   196.698 |     2.4%
react-hooks/rules-of-hooks                      |   113.093 |     1.4%
@anubra266
Copy link
Collaborator

anubra266 commented Oct 7, 2024

@Faithfinder Could you give more context on your project that might help reproduce. I've got something like:

1:

✖ 33 problems (13 errors, 20 warnings)

Rule                                   | Time (ms) | Relative
:--------------------------------------|----------:|--------:
@pandacss/file-not-included            |   498.770 |    85.9%
@pandacss/no-physical-properties       |    13.915 |     2.4%
@pandacss/no-margin-properties         |    13.809 |     2.4%
@pandacss/no-hardcoded-color           |    11.742 |     2.0%
@pandacss/no-invalid-token-paths       |     9.603 |     1.7%
@pandacss/no-unsafe-token-fn-usage     |     9.245 |     1.6%
@typescript-eslint/no-unused-vars      |     5.765 |     1.0%
@pandacss/no-dynamic-styling           |     4.017 |     0.7%
@pandacss/no-config-function-in-source |     3.321 |     0.6%

2:

Rule                                   | Time (ms) | Relative
:--------------------------------------|----------:|--------:
@pandacss/file-not-included            |   574.780 |    97.8%
@typescript-eslint/no-unused-vars      |     2.458 |     0.4%
@pandacss/no-margin-properties         |     1.336 |     0.2%
@pandacss/no-unsafe-token-fn-usage     |     1.277 |     0.2%
@pandacss/no-config-function-in-source |     0.996 |     0.2%
@pandacss/no-hardcoded-color           |     0.768 |     0.1%
@pandacss/no-invalid-token-paths       |     0.691 |     0.1%
no-control-regex                       |     0.544 |     0.1%
no-misleading-character-class          |     0.442 |     0.1%

@Faithfinder
Copy link
Author

Huh. Well, I don't think I can give you a repro, as that's a closed-source project, but from a technical perspective, it's nothing too special.

  • A Vite SPA.
  • Around 260k lines of code according to git diff --shortstat 'git hash-object -t tree /dev/null'
  • pnpm panda > 🐼 info [hrtime] Successfully extracted css from 730 file(s) ✨ (1554.56ms)
  • Way too many dependencies and styling solutions.
Eslint config:
import globals from "globals";
import pluginJs from "@eslint/js";
import comments from "@eslint-community/eslint-plugin-eslint-comments/configs";
import pluginTs from "typescript-eslint";
import pluginReact from "eslint-plugin-react";
import hooksPlugin from "eslint-plugin-react-hooks";
// import panda from "@pandacss/eslint-plugin";

export default pluginTs.config(
  {
    name: "settings",
    languageOptions: {
      globals: { ...globals.browser },
      parserOptions: {
        project: ["tsconfig.json", "tsconfig.test.json"],
        tsconfigRootDir: import.meta.dirname,
      },
    },
    settings: {
      react: {
        version: "detect",
      },
    },
  },
  pluginJs.configs.recommended,
  ...pluginTs.configs.recommendedTypeChecked,
  pluginReact.configs.flat.recommended,
  comments.recommended,
  // {
  //   name: "Panda CSS",
  //   plugins: {
  //     "@pandacss": panda,
  //   },
  //   rules: {
  //     ...panda.configs.recommended.rules,
  //   },
  // },
  {
    name: "React Hooks",
    plugins: {
      "react-hooks": hooksPlugin,
    },
    rules: hooksPlugin.configs.recommended.rules,
  },
  {
    name: "Disable bad recommendations, enable missing useful rules",
    rules: {
      "no-multi-assign": "error",
      "no-return-assign": ["error", "always"],
      "require-atomic-updates": "error",
      eqeqeq: ["error", "always", { null: "ignore" }],
      "no-console": "warn",
      "no-lonely-if": "warn",
      "no-sequences": "warn",
      "no-unneeded-ternary": "warn",
      "no-var": "error",
      "prefer-const": ["warn", { destructuring: "all" }],
      "prefer-object-has-own": "warn",
      "no-restricted-imports": [
        "error",
        {
          paths: [
            {
              name: "react-redux",
              importNames: ["useSelector", "useDispatch", "useStore"],
              message: "Please use version in `src/redux/hooks.ts` instead",
            },
          ],
        },
      ],

      "@typescript-eslint/no-unsafe-argument": "off",
      "@typescript-eslint/no-unsafe-return": "off",
      "@typescript-eslint/no-unsafe-member-access": "off",
      "@typescript-eslint/no-unsafe-call": "off",
      "@typescript-eslint/no-unsafe-assignment": "off",
      "@typescript-eslint/no-unused-expressions": [
        "error",
        { allowShortCircuit: true, allowTernary: true, enforceForJSX: true },
      ],
      "@typescript-eslint/no-misused-promises": [
        "error",
        {
          checksVoidReturn: {
            arguments: false,
            attributes: false,
          },
        },
      ],
      "@typescript-eslint/consistent-type-exports": ["error", { fixMixedExportsWithInlineTypeSpecifier: true }],
      "@typescript-eslint/consistent-type-imports": ["error", { fixStyle: "inline-type-imports" }],
      "@typescript-eslint/no-confusing-void-expression": [
        "warn",
        { ignoreArrowShorthand: true, ignoreVoidOperator: true },
      ],
      "@typescript-eslint/no-loop-func": "error",
      "@typescript-eslint/no-require-imports": "error",
      "@typescript-eslint/no-unnecessary-condition": "error",
      "@typescript-eslint/only-throw-error": [
        "error",
        {
          allowThrowingAny: true,
          allowThrowingUnknown: true,
        },
      ],
      "@typescript-eslint/prefer-find": "warn",
      "@typescript-eslint/prefer-includes": "warn",
      "@typescript-eslint/prefer-return-this-type": "error",
      "@typescript-eslint/prefer-ts-expect-error": "error",
      "@typescript-eslint/promise-function-async": "error",
      "@typescript-eslint/require-array-sort-compare": "error",
      "@typescript-eslint/return-await": ["error", "always"],
      "@typescript-eslint/no-empty-function": ["error", { allow: ["private-constructors", "protected-constructors"] }],
      "@typescript-eslint/no-unused-vars": ["warn", { ignoreRestSiblings: true }],
      "@typescript-eslint/no-use-before-define": [
        "error",
        { functions: false, typedefs: false, enums: false, variables: false },
      ],

      "react/prop-types": "off",
      "react/jsx-no-constructed-context-values": "warn",
      "react/jsx-key": [
        "error",
        {
          checkFragmentShorthand: true,
          checkKeyMustBeforeSpread: true,
          warnOnDuplicates: true,
        },
      ],
      "react/button-has-type": "error",
      "react/hook-use-state": "error",
      "react/jsx-fragments": "warn",
      "react/jsx-no-useless-fragment": ["warn", { allowExpressions: true }],
      "react/jsx-pascal-case": ["warn", { allowNamespace: true }],
      "react/react-in-jsx-scope": "off",
      "react/jsx-uses-react": "off",
      "react/no-unused-class-component-methods": "error",
      "react/prefer-stateless-function": "warn",

      "@eslint-community/eslint-comments/disable-enable-pair": ["error", { allowWholeFile: true }],
    },
  },
  {
    name: "Undesired disables",
    // Disabled during initial linting setup for violations, enable one by one
    // Comment out this section and run `pnpm eslint src -f summary`
    // to see a summary and choose with lower number for easier fixes
    rules: {
      "@typescript-eslint/no-empty-function": "off",
      "react/button-has-type": "off",
      "react/display-name": "off",
      "react/hook-use-state": "off",
      "react/jsx-no-constructed-context-values": "off",
      "react/jsx-pascal-case": "off",
      "react/no-children-prop": "off",
      "react/no-unescaped-entities": "off",
      "require-atomic-updates": "off",
    },
  },
  {
    files: ["src/**/*.js?(x)"],
    rules: {
      ...pluginTs.configs.disableTypeChecked.rules,
    },
  },
);
PC stats
  Model Name:	MacBook Pro
  Model Identifier:	Mac15,7
  Model Number:	MRW13LL/A
  Chip:	Apple M3 Pro
  Total Number of Cores:	12 (6 performance and 6 efficiency)
  Memory:	18 GB

Anything in particular I can tell you that's not a repo dump?

@anubra266
Copy link
Collaborator

@Faithfinder Didn't have anything particular in mind. Was just looking out for any major differences in your project

@anubra266
Copy link
Collaborator

In the mean time @Faithfinder I'll look into some optimizations like memoization.

@Faithfinder
Copy link
Author

I'm happy to share configs or run a diagnostic if you ask me to, but IMO just one rule @pandacss/no-invalid-token-paths taking 3 minutes when the whole build of the app is 1.5 minutes means there's something very wrong on a code path somewhere.

@anubra266
Copy link
Collaborator

anubra266 commented Oct 8, 2024

@Faithfinder Did some improvements. Let me know if this has any impact

https://github.com/chakra-ui/eslint-plugin-panda/releases/tag/%40pandacss/eslint-plugin%400.2.0

@Faithfinder
Copy link
Author

Looks like a big improvement, but not enough for it to become usable:

Rule                                            |  Time (ms) | Relative
:-----------------------------------------------|-----------:|--------:
@pandacss/no-hardcoded-color                    | 111674.958 |    22.1%
@pandacss/no-unsafe-token-fn-usage              | 107499.765 |    21.2%
@pandacss/no-invalid-token-paths                | 102651.342 |    20.3%
@pandacss/no-dynamic-styling                    |  93657.633 |    18.5%
@pandacss/no-property-renaming                  |  77170.474 |    15.2%
@pandacss/file-not-included                     |   4092.441 |     0.8%
@typescript-eslint/no-confusing-void-expression |   2254.596 |     0.4%
@typescript-eslint/no-misused-promises          |   1457.956 |     0.3%
@typescript-eslint/no-unused-vars               |    737.505 |     0.1%
react/no-direct-mutation-state                  |    682.282 |     0.1%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants