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

Mongoose slows down performance of VSCode (TSServer) by a lot #10349

Closed
ShadiestGoat opened this issue Jun 12, 2021 · 217 comments
Closed

Mongoose slows down performance of VSCode (TSServer) by a lot #10349

ShadiestGoat opened this issue Jun 12, 2021 · 217 comments
Labels
typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@ShadiestGoat
Copy link
Contributor

Do you want to request a feature or report a bug?

bug

What is the current behavior?

It slows down vscode by a lot, even with small projects. I have a very small project, with like 2 small schemas, and the 2 other files, containing on average 160 lines of code, and vscode slows down a lot as soon as I install mongoose. This does not happen when I install most other libraries (haven't tested them all lmao). If I uninstall mongoose, it comes back and works perfectly normal.
To clarify "slowing down" means that typescript language server needs 3-5 seconds to realise that I'm importing somethign invalid, and just vscode in general to realise I'm importing something that's never used takes around 2-4 seconds. Usually it happens in under a second so like.. you know...
And it's not like vscode is taking a lot of ram/cpu either, it just grows slow.
Btw I think this is a mongoose issue, since it happens with no other library, its a special case here
Reloading typescript server or project doesn't help

If the current behavior is a bug, please provide the steps to reproduce.

Have vscode to edit your code
Install mongoose on your current project (npm i mongoose

My tsconfig.json:

{
    "compilerOptions": {
        "allowJs": true,
        "moduleResolution": "Node",
        "esModuleInterop": true,
        "target": "ES6",
        "resolveJsonModule": true,
        "outDir": "./dist",
        "checkJs": true,
        "module": "CommonJS",
        "lib": ["ESNext"]
    },
    "include": ["src"]
}

What is the expected behavior?

It to not be like this, lmao.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

Node: v16.2.0
Mongoose: 5.12.13
Linux: 5.12.7-arch1-1

@vkarpov15
Copy link
Collaborator

Interesting, can you please provide an example project that demonstrates this? I haven't noticed this but I might be missing something.

@vkarpov15 vkarpov15 added this to the 5.x Unprioritized milestone Jun 14, 2021
@vkarpov15 vkarpov15 added needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue and removed performance labels Jun 14, 2021
@ShadiestGoat
Copy link
Contributor Author

ShadiestGoat commented Jun 14, 2021

Mm well I can replicate it with very little:

import { model, Model, Schema } from "mongoose";

export interface UserSH {
    username: string,
    password: string,
    maxMb: number,
    submitted: string[],
    id: string
}

export const UserSchema = new Schema<UserSH, Model<UserSH>, UserSH>({
    id: "string",
    maxMb: "number",
    username: "string",
    submitted: ["string"],
    password: "string"
})


uiyasdjklsadias //error this baby is undefined

The thing that 'triggers' it is creating the schema. If I just remove the schema creation, its all good

(the only files in the project are the default ones, mongoose, [email protected], and src/index.ts, contents of which are above. Otherwise its newly created)

@mjfwebb
Copy link

mjfwebb commented Jul 3, 2021

I can confirm that I am also experiencing a degradation in Typescript performance due to Mongoose.

@jasonwwl
Copy link

jasonwwl commented Jul 5, 2021

me too

@cainaf
Copy link

cainaf commented Jul 6, 2021

I can confirm that too.

I was using @types/mongoose before and just removed it in favor of mongoose own type definitions. It was like snapping two fingers, boom, vscode was now super slow. Simple autocompletes and validations are taking now over 5 or even 10 seconds sometimes in all project files.

@vkarpov15 vkarpov15 modified the milestones: 5.x Unprioritized, 5.13.3 Jul 7, 2021
@xiaoxin-sky
Copy link

我也能够明显感觉到,mongoose 使得 vscode 加载类型提示变慢。但是仅限于加载 mongoose 相关的内容变慢。

@ShadiestGoat
Copy link
Contributor Author

Really? For me it slows all content, not just mongoose related...

@cainaf
Copy link

cainaf commented Jul 12, 2021

Same as @ShadiestGoat for me. Even eslint gets very slow. If I delete index.d.ts from mongoose lib inside node_modules, performance of everything becomes instant again.

@fercg16
Copy link

fercg16 commented Jul 13, 2021

I can confirm it slows down all the content for me too.

I did as @cainaf said to verify it was mongoose, I deleted index.d.ts and..., vs code was running fine as hell again.
I restored index.d.ts and the performance heavily dropped down again.

@ShadiestGoat
Copy link
Contributor Author

Well removing new Schema<UserSH, Model<UserSH>, UserSH> removes the issues with performance (on the script I gave above)

@ghost
Copy link

ghost commented Jul 13, 2021

I am experiencing the problem since Mongoose has adopted it's own official type definition. I have a workaround that is to delete index.d.ts of mongoose in node_module and then npm i -D -E @types/[email protected] to temporarily use the DefinitelyTyped type definition.

@TigranAvagyan18
Copy link

Experiencing same problem . Any solutions to this?

@vkarpov15 vkarpov15 modified the milestones: 5.13.3, 5.13.4 Jul 16, 2021
@qafoori
Copy link

qafoori commented Jul 16, 2021

And I have the same problem in vscode. I was using postgresql in my project and for some reason I migrated to mongodb (using mongoose). vscode has been super slow since I migrated to mongodb.

@TigranAvagyan18
Copy link

I am experiencing the problem since Mongoose has adopted it's own official type definition. I have a workaround that is to delete index.d.ts of mongoose in node_module and then npm i -D -E @types/[email protected] to temporarily use the DefinitelyTyped type definition.

Did u get any performance change after performing that?

@nikolaninkovninkov
Copy link

This really needs a fix... Programming is not possible like this.

@ShadiestGoat
Copy link
Contributor Author

So I'm looking into potential reasons for this (just started). To me it just looks like its a long build of the problem, where the types file is just too long/complex. For example, taking an older version of mongoose (eg. 3.11.18), the issue was starting to present itself, given that it decreased performance by a lot, but no where near this level.
It could be that to solve this problem the types for this module need a major rework. I also believe this should be a priority.

@ShadiestGoat
Copy link
Contributor Author

I'm not sure how much it would help, but perhaps splitting the types into multiple files may help? I'm pretty sure VSCode uses tsserver, which (at least I'm pretty sure of which) has to load an entire file at once

@ShadiestGoat
Copy link
Contributor Author

Oh and forgot to mention this earlier, but, I have a pretty good laptop I'm coding on. HP Omen 15, with ryzen 7 4800H, SSD, and a gpu, so it isn't like I just gotta get a better laptop

@Thisura98
Copy link

Thisura98 commented Jul 23, 2021

I created a new TypeScript Node project and it worked fine even just after installing mongoose. However, as soon as I started creating a schema and creating a model from it, things started going south.

This is what the schema + model code looks like.

import * as mongoose from 'mongoose';

export const testSchema = new mongoose.Schema({
    name: String,
    time: Number,
    age: Number
});

export const testModel = mongoose.model('TestModel', testSchema);

I also checked by importing the model and Schema individually instead of using * as but the outcome was the same.

I am a beginner to the world of Mongo and Node so unfortunately I am not knowledgable enough to debug this issue. So instead for the time being, I am going to resort to using the vanilla MongoDB Driver for Node: link.

Sorry mongoose.

----- EDIT -----

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",   
    "module": "commonjs",   
    "strict": true,             
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

package versions

@Thisura98
Copy link

Thisura98 commented Jul 23, 2021

Decided to give it one more shot by taking into consideration feedback by @TigranAvagyan18. And I got it to work!

Commands:

npm i [email protected] --save
npm i @types/[email protected] --save

Summary:

  • Downgrade to last version before Mongoose's own TS types
  • Install DefinitelyTyped's Mongoose types.

My existing code worked with these versions without issues. Code completion performance is also back! It feels so good to have the snappy completion back.

As a side note, Mongoose introduced their own types in version 5.11.0 according to this. 5.10.19 was the last version released before that according to this

I will test some more tonight to see if my current code was affected by this downgrade and update this post if I find any.

@cainaf
Copy link

cainaf commented Jul 23, 2021

Although returning to @types/mongoose does solve performance problem, it also may break your code. It sure did mine.

When we migrated to mongoose own types, we had to fix more than 500 typescript errors (the code was fine and would work requiring no change, it's just the way types are implemented that vary from one to another, the requirement of methods and their return types).

If we were to fallback to @types/mongoose again, that's what's waiting us:

Captura de Tela 2021-07-23 às 14 27 34

And then, when the problem here is solved, we would have to change all over again. not cool =/

@ShadiestGoat
Copy link
Contributor Author

Using @types/mongoose is a hasckish workaround, that may cause a lot of issues. It is not a solution.

@Automattic Automattic deleted a comment from nidhalmessaoudi Aug 1, 2022
@vkarpov15
Copy link
Collaborator

@Uzlopak not really. That article's only about detecting unexpected large TS files, which is nice but typically not the cause of TypeScript performance issues.

@vkarpov15
Copy link
Collaborator

I've confirmed that the cause of this slowdown is #11563. It looks like the cause is that #11563 makes heavy use of infer, which can be extremely slow. Here's tsc --extendedDiagnostics with 77d2c70:

Instantiations:             392799
Memory used:               213855K
Assignability cache size:    29100
Check time:                  2.47s
Total time:                  3.25s

Now if I replace ObtainSchemaGeneric with the below:

type ObtainSchemaGeneric<TSchema, alias extends 'EnforcedDocType' | 'M' | 'TInstanceMethods' | 'TQueryHelpers' | 'TVirtuals' | 'TStaticMethods' | 'TPathTypeKey' | 'DocType'> = any;

I get:

Instantiations:              60772
Memory used:               163552K
Assignability cache size:    16624
Check time:                  1.67s
Total time:                  2.44s

We'll do some more digging to see what we can do.

@mohammad0-0ahmad do you have any ideas how we might make your auto typed schemas code work without relying on infer?

@mohammad0-0ahmad
Copy link
Contributor

mohammad0-0ahmad commented Aug 1, 2022

@vkarpov15 @Uzlopak, while working on that PR, I had tested multiple ways to get the best performance without have a lot of changes on the types and prevent as much as possible of regressions. I thought by obtaining the correct doc type from the beginning "when declaring the schema" might allow us to refactor the entire ts code to avoid unnecessary operations that already exist to get the correct doc type, like lean required_id and so on.
I am not really sure if that will make things better, I wonder if we should to rely on a specific field or benchmark to measure the changing of the performance like total time, check time or maybe someone else, I couldn't find full documentation on all extendedDiagnostics option result fields.

@Uzlopak Uzlopak closed this as completed Aug 1, 2022
@Uzlopak Uzlopak reopened this Aug 1, 2022
@mohammad0-0ahmad
Copy link
Contributor

mohammad0-0ahmad commented Aug 1, 2022

With other words, I wonder if there is a field that represent the actual waiting time to show intellisense message "or suggestions fields" that make user feel that it is slow. Even if that field affects by end user pc specs, we can maybe specify a custom memory, CPU or cache configuration in typescript benchmark workflow action file "if that possible".

@mohammad0-0ahmad
Copy link
Contributor

I've noticed as well that the current test file that we have rely on manual typed schema, not the auto one which give even higher Instantiations result. So I think we might need as well to create a separate one for the auto typed one to be able to target the different approaches while make any change on the types.

@mohammad0-0ahmad
Copy link
Contributor

Something like:

- const schema = new Schema<User>({
+ const schema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true },
  avatar: String
});

- const UserModel = model<User, UserModelInterface>('User', schema);
+ const UserModel = model('User', schema);

@Uzlopak
Copy link
Collaborator

Uzlopak commented Aug 1, 2022

Sry, misclicked with my mobile.

Well tbh I am still kind of bummed since the heavy regressions i caused with the aggregation pipeline typings. But I actually was quite happy about the changes we made regarding the typings. We separated the typings in multiple logical units and tbh. some of the typings are kind of simple. So we can actually kind of say that some type files should be not critical regarding performance (simple interfaces without any special typescript logic). Maybe we should focus on further separating remaining index.d.ts till we just import typings from other files. Then we optimize one schema after the other.

@mohammad0-0ahmad
Copy link
Contributor

mohammad0-0ahmad commented Aug 1, 2022

I've confirmed that the cause of this slowdown is #11563. It looks like the cause is that #11563 makes heavy use of infer, which can be extremely slow. Here's tsc --extendedDiagnostics with 77d2c70:

Instantiations:             392799
Memory used:               213855K
Assignability cache size:    29100
Check time:                  2.47s
Total time:                  3.25s

Now if I replace ObtainSchemaGeneric with the below:

type ObtainSchemaGeneric<TSchema, alias extends 'EnforcedDocType' | 'M' | 'TInstanceMethods' | 'TQueryHelpers' | 'TVirtuals' | 'TStaticMethods' | 'TPathTypeKey' | 'DocType'> = any;

I get:

Instantiations:              60772
Memory used:               163552K
Assignability cache size:    16624
Check time:                  1.67s
Total time:                  2.44s

We'll do some more digging to see what we can do.

@mohammad0-0ahmad do you have any ideas how we might make your auto typed schemas code work without relying on infer?

@vkarpov15 I don't think there is a way to do that without using infer It might be helpful if there is a way to store the inference result of the schema to avoid re infer generics multiple time.
It might be helpful to ask someone of TS team like @sandersn.
I hope I didn't bother you by mentioning here.

@sandersn
Copy link
Contributor

sandersn commented Aug 2, 2022

@andrewbranch has been the TS team member investigating the mongoose types.

@vkarpov15
Copy link
Collaborator

I did some more digging, haven't made much progress. Managed to make a token improvement by removing one of the infer paths in ObtainSchemaGeneric, but that doesn't make much of a dent. It does seem that infer is necessary here, as @mohammad0-0ahmad indicated, so we'll have to figure out an alternative approach to make tsc not blow up.

@mrfy
Copy link

mrfy commented Aug 5, 2022

@vkarpov15
In our project we also struggled with the slow performance of TS-server, today we did some tests and disabled all vscode extensions, performance improved drastically! In our case, it turned out that one particular extension affects the TS-server performance, turning it off makes everything run smoothly. Please check on your enviroment

@vkarpov15
Copy link
Collaborator

I'm gonna close this because of #12284 . We'll do some separate work to improve our TS benchmarks with #12320.

If you're running into a similar issue, please create a standalone repro script that demonstrates slow performance using tsc --extendedDiagnostics. It is practically impossible for us to debug "my VSCode is slow", we have no experience with VSCode internals. So unless you can demonstrate slow TypeScript performance, there isn't much we can do unfortunately.

@Automattic Automattic locked as resolved and limited conversation to collaborators Aug 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
typescript Types or Types-test related issue / Pull Request
Projects
None yet
Development

No branches or pull requests