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

mknichel/dedupe strings in module layers #18340

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

mknichel
Copy link

@mknichel mknichel commented Apr 19, 2024

What kind of change does this PR introduce?

This pull request adds a layer of caching for strings that could be duplicated in modules across multiple layers. This change was motivated by an observation that there were many strings in the heap duplicated in a Next.js application that uses App Router, which uses layers in the implementation. After this pull request, these strings were deduplicated saving the memory for any file that appears in multiple layers.

The cache here is associated with the compilation in a weak map so it can be garbage collected after the compilation finishes.

There should be no visible behavior difference after this pull request.

Did you add tests for your changes?

New tests were not added since the behavior should be covered by existing integration tests that use layers.

Does this PR introduce a breaking change?

No, this PR is not a breaking change. No user visible behavior is affected.

What needs to be documented once your changes are merged?

No changes would need to be documented after this pull request. This pull request only affects internal implementation details.

Copy link

linux-foundation-easycla bot commented Apr 19, 2024

CLA Not Signed

@webpack-bot
Copy link
Contributor

For maintainers only:

  • This needs to be documented (issue in webpack/webpack.js.org will be filed when merged)
  • This needs to be backported to webpack 4 (issue will be created when merged)

} else {
moduleLayerCache.set(module.userRequest, data);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move it to method, to avoid duplicate logic (for example to the compilation class)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Sorry for the delay. Let me know if this is what you had in mind.

lib/NormalModule.js Outdated Show resolved Hide resolved
lib/NormalModule.js Outdated Show resolved Hide resolved
lib/NormalModule.js Outdated Show resolved Hide resolved
lib/ModuleLayerCache.js Outdated Show resolved Hide resolved
@mknichel mknichel marked this pull request as ready for review May 13, 2024 17:38
Copy link
Member

@sokra sokra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to put that behind and experiments flag.

Currently this is not a plain improvement. It will leak memory as all module sources stay in the cache even if you remove the import to the module. I think it would be better to remove modules that are not longer in the compilation from the cache.

@mknichel
Copy link
Author

FYI @alexander-akait, @sokra and I met to discuss a path forward. Instead of this approach, we want to add a generic string and Buffer interning logic inside https://github.com/webpack/webpack-sources. In Webpack, we can enable + disable interning via an experiment and at the start and end of a compilation so that users can opt in to this behavior and no memory is leaked beyond the compilation. I'm going to start prototyping that solution. @sokra will be unavailable starting in 2 days, so let me know if this plans sounds good to you and whether you might be able to review that while @sokra is OOO.

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

Successfully merging this pull request may close these issues.

None yet

4 participants