Skip to content

Conversation

RobinMalfait
Copy link
Member

@RobinMalfait RobinMalfait commented Oct 21, 2025

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

  1. All existing tests pass

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:
image

On the current main branch, this looks like:
image

In this PR, the memory usage looks like:
image

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:
image

Now we're sort of back to the current situation on main:
image

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.
@RobinMalfait RobinMalfait marked this pull request as ready for review October 21, 2025 14:40
@RobinMalfait RobinMalfait requested a review from a team as a code owner October 21, 2025 14:40
Copy link
Contributor

@thecrypticace thecrypticace left a 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 🔥

@RobinMalfait RobinMalfait merged commit 56e7f3b into main Oct 21, 2025
7 checks passed
@RobinMalfait RobinMalfait deleted the fix/improve-memory branch October 21, 2025 14:55
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

Successfully merging this pull request may close these issues.

2 participants