-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Improve memory usage during canonicalization #19171
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
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This will allow us to add data to the design system itself instead of using module-scope Map's where the key is pointing to the DesignSystem. This has the benefit that all data is tied to a DesignSystem. If you don't need a design system anymore, then garbage collection will kick in and remove everything. If we rely on module scope maps, then we have to do the cleanup (or use WeakMap, but that requires more testing to know if that _actually_ works when multiple WeakMap instances reference a DesignSystem). Since it's a general purpose object, we have to ensure that you can't accidentally override data... because of this, the storage is typed such that the keys must be Symbols.
We need to enhance the design system to setup the storage on the design system itself. We can use the `prepareDesignSystemStorage` to "promote" the current `BaseDesignSystem` to the new `DesignSystem` where the storage is properly setup. This way, TypeScript will only allow you to access the necessary storage parts if you are operating on a DesignSystem that has the storage setup already. Now it's up to us to ensure the storage is setup properly in the `prepareDesignSystemStorage` function.
We only really need it in this file, this will also make it a bit easier to further enhance the design system storage.
Instead of nesting the `designSystem` as part of the nested signature options object, we move the design system up. This commit is just here to make the easy change later. We want to store all caches on the design system itself, so by hoisting it up, we can make a nicer change in the near future.
Some codemods used some internal canonicalization stuff, so this commit makes that work.
thecrypticace
approved these changes
Oct 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested this in IntelliSense too and the memory usage there is now stable 🔥
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR drastically improves the memory usage when performing canonicalization if you swap out the underlying DesignSystem often. This will be most noticeable in Intellisense.
The big issue we had is that we used module scoped Map objects where we cache data based on the DesignSystem. If you then create new design systems (often), then the cache would just keep growing and growing.
This PR solves that by essentially storing all the caches on the Design System itself. This way, when you throw away a Design System, all the caches go with it.
Another approach would've been to use a WeakMap, but then we would have to make sure that no strong references to the DesignSystem exist anywhere else, otherwise we would still have the same memory issues.
Note: make sure to go commit by commit and use
?w=1
to ignore whitespace changes.Test plan
Not super sure how to test this as part of the test suite without making it slow But I also don't think that's super necessary either. Here is an experiment I did where I introduce 5 design systems:

On the current

main
branch, this looks like:In this PR, the memory usage looks like:

The memory usage is stable, but to actually prove that we can still track multiple design systems, let's track them all in a

Set
so garbage collection cannot get rid of the unused design system objects:Now we're sort of back to the current situation on

main
: