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

Guidance on reducing heap usage of large typings? #37214

Open
Eyas opened this issue Mar 4, 2020 · 12 comments
Open

Guidance on reducing heap usage of large typings? #37214

Eyas opened this issue Mar 4, 2020 · 12 comments
Labels
Docs The issue relates to how you learn TypeScript

Comments

@Eyas
Copy link
Contributor

Eyas commented Mar 4, 2020

I maintain google/schema-dts which generates typings for schema.org JSON-LD. The generated typings are ~10k loc and involves a lot of type unions (e.g. Thing can be Organization or CreativeWork or Person or ...), and these can get pretty nested.

Compiling these works for me and the vast majority of users. But I get constant reports of JavaScript heap OOM errors from users consuming the typings. See google/schema-dts#34. I haven't been able to repro this at all, but I'm still hoping for some guidance on getting a better memory footprint for the type checker.

FYI, the .d.ts file looks something like this: https://unpkg.com/[email protected]/schema.d.ts

Questions (I'd take answers to any of these):

  1. Are there better strategies for writing these in a more memory friendly way? e.g. naming intermediate types, or declaring all properties in one huge object and defining respective types in terms of Pick<>?
  2. Are there any profiling tools that anyone would recommend using to track this down?
  3. any other advice is appreciated.

Unfortunately splitting the types up isn't an option (at least not obviously) because the types are deeply self referential.

@RyanCavanaugh RyanCavanaugh added the Docs The issue relates to how you learn TypeScript label Mar 9, 2020
@DanielRosenwasser
Copy link
Member

Hey @Eyas, I saw your post on https://twitter.com/EyasSH/status/1257373760216281091. We do have some docs on https://github.com/microsoft/TypeScript/wiki/Performance, and @amcasey has a branch to diagnose which line of code is causing lots of types to be generated internally (#37785). We're trying to understand what profiling tools would be useful for these situations.

I think one thing that is reasonable is to tell your users in the meantime to increase their heap sizes when running TypeScript. I know that in VS Code this can be done with "typescript.tsserver.maxTsServerMemory", and on Node I think this is done with --max-old-space-size.

@amcasey
Copy link
Member

amcasey commented May 4, 2020

Note that you'd want to run that instrumented build on the consumer of the .d.ts file to help figure out which parts are the most expensive for them. In my experience, profiling the producer tends to reveal few, if any issues.

@amcasey
Copy link
Member

amcasey commented May 4, 2020

@Eyas I'm probably missing something obvious, but the npm scripts I see produce a bunch of separate .d.ts files instead of one big, consolidated one, like you linked above. How can I produce one of those locally?

@Eyas
Copy link
Contributor Author

Eyas commented May 5, 2020

The packaged .d.ts is here: https://www.npmjs.com/package/schema-dts


If you're trying it from source, running "npm run pkg" will create the single .d.ts in "/dist/schema".


The multiple files you're seeing are the .d.ts files of the generator CLI. It makes an http request to an arbitrary .NTriples schema declaration (by default latest schema.org schema). That final output (TS defs of schema.org schema) is what contains huge unions that seem to be causing people to run into problems

@amcasey
Copy link
Member

amcasey commented May 5, 2020

@Eyas Thanks! Yes, I'd like to be able to build it locally, so I can play around a bit.

We've definitely had some problems with huge unions, especially when they're operated on by mapped types. Things should be somewhat better in 3.9 (now in RC). The easiest way to play with the latest version is to install the TS Nightly extension.

It's something of an art, but I've definitely seen some impressive perf improvements from naming intermediate types (because it can short-circuit structural type comparison, which is very expensive).

@Eyas
Copy link
Contributor Author

Eyas commented May 5, 2020

Helpful to know about naming intermediate types! That also gives me a few avenues to try

@amcasey
Copy link
Member

amcasey commented May 5, 2020

Here's one I thought was particularly amazing (and for which I can take no credit): mui/material-ui#19996

@amcasey
Copy link
Member

amcasey commented May 5, 2020

As for identifying where to apply this sort of optimization, we're still working on that, but #37785 is our current best attempt. (Looking now, I see that the bot silently failed to create a standalone build - I'll investigate.)

@weswigham
Copy link
Member

Probably worth mentioning: I have heard reports in other issues that the node version in use can heavily affect this. 8-10 predate v8 pointer compression (and other optimizations), notably, and can OOM in places where node 12+ would not. So you should also ask what node your users are running, if possible; it could be critical to the repro.

@Eyas
Copy link
Contributor Author

Eyas commented May 5, 2020

Got it. Thanks. I've seen reports on Node 10 and 12, although a lot of reports are missing Node version.

@amcasey
Copy link
Member

amcasey commented May 9, 2020

I ran #37785 on your example and it revealed precisely nothing. So either this is a different class of slowdown than we were expecting or the tool is useless on .d.ts files. I'll have to investigate more to figure out which.

@Eyas
Copy link
Contributor Author

Eyas commented Aug 11, 2020

@amcasey if it helps/narrows anything down, some users are reporting that TypeDoc is also OOMing with the linked library. Not sure if TypeDoc uses any of the typescript lib when running through types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Docs The issue relates to how you learn TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants