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

Parsing Svelte files with types is slow, and slows down more as more files are added to project #1084

Open
2 tasks done
mcous opened this issue Feb 25, 2025 · 2 comments
Open
2 tasks done
Labels
perf Improvement of performance

Comments

@mcous
Copy link

mcous commented Feb 25, 2025

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

9.21.0

What version of eslint-plugin-svelte are you using?

3.0.0-next.18

What did you do?

Configuration
import ts from 'typescript-eslint';
import svelteParser from 'svelte-eslint-parser';

export default ts.config({
  files: ['**/*.svelte'],
  languageOptions: {
    parser: svelteParser,
    parserOptions: {
      parser: ts.parser,
      projectService: true,
      extraFileExtensions: ['.svelte'],
      tsconfigRootDir: import.meta.dirname,
    },
  },
});
<script lang="ts">
  let { name = 'A' }: { name: number } = $props();
</script>

<h1>Hello from Component {name}</h1>

What did you expect to happen?

With type-checking enabled, and without any lint rules enabled, linting a Svelte file should take about the same amount of time as linting a TypeScript file. Lint times should be roughly on par with type-checking times.

What actually happened?

When types are enabled, the linting time of Svelte components increases dramatically as the number of files in the project (Svelte or otherwise) increase. This occurs with both projectService: true and project: './tsconfig.json'. This lint increase occurs even if the ESLint config doesn't enable any rules. The performance issue appears to happen during the parse stage.

In a simple project with 1000 Svelte files and 1000 TS files, and the ESLint config above (parsers configured, no rules enabled), my type-checking / lint times are:

Task Time (M2 MacBook Air)
Type-check (svelte-check) 7 seconds
Lint TS, with projectService 4 seconds
Lint Svelte, without types 3 seconds
Lint Svelte, with projectService 45 seconds
Lint Svelte, with project 20 seconds

In a closed-source real-life project that I work on, linting our TS files takes under a minute, while linting the Svelte files takes 5 to 8 minutes depending on the machine.

Link to GitHub Repo with Minimal Reproducible Example

I've created a reproduction repository with a few simple ESLint configs that configure the TS and Svelte parsers and nothing else, along with a script to create fixture components and modules:

https://github.com/mcous/eslint-svelte-ts-perf

Additional comments

Thanks for all your work on this project! I'm very happy to dedicate time and energy to investigating this issue further, but I'd need some guidance to do so.

I think this issue may be related to #954

@baseballyama
Copy link
Member

Thank you! This is a great REPL, and I was able to reproduce the issue. I’ll take some time to investigate it soon.

@43081j
Copy link
Contributor

43081j commented Mar 27, 2025

i had a quick look at this

one thing to note is that this block of code:
https://github.com/sveltejs/svelte-eslint-parser/blob/73479f9dd3ca7c27cd0ce9a65f4885b13c0132de/src/parser/script.ts#L59-L77

will create a new program for every file. TSESLint will realise there's no program or service, and create one under the hood.

so maybe there is some saving to be had by reusing a project/program somewhere in the parser

similarly, we actually parse nothing (but still create a program) in order to detect if something is TSESLint:
https://github.com/sveltejs/svelte-eslint-parser/blob/73479f9dd3ca7c27cd0ce9a65f4885b13c0132de/src/parser/parser-object.ts#L56-L72

this could probably just use value.meta.name, no? it will be set to "typescript-eslint/parser" or some such thing

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

No branches or pull requests

3 participants