ade8d7cdc4
This fixes memory leaks caused by `prevExports` in react-refresh-utils. It happens in code like the following: ```tsx const DATA = Array.from({ length: 100000 }, (_, i) => Math.random()); export const App = () => { return ( <div> <div>REWRITE_HERE</div> <div>{DATA.length}</div> </div> ); }; ``` After we edit this file to trigger fast refresh, previous `DATA` will be still retained in the memory since it forms `App(new) -> prevExports -> App(old) -> DATA` reference chain (there is some screenshots [here](https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/766)). I believe there is no reason to retain the whole exports as `prevExports`. We can just retain "signature" (`string[]`). By only holding this, we no longer create reference to the old exports, which fixes the memory leak here. Note that I filed a similar PR in https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/766 and also https://github.com/naruaway-sandbox/fast-refresh-hmr-memory-leak-demo is a reproducible example of this issue, which also explains that interestingly this issue is not easily solved for Vite. ## Should we fix it? I think yes, as long as there is no unintended side effect, it's better to fix it since we cannot predict whether users would load large payload AND does Fast Refresh many times without reloading the browser or not. In [this extreme case](https://github.com/naruaway-sandbox/fast-refresh-hmr-memory-leak-demo), it eats several hundred mega bytes of RAM. ## Verification I confirmed that the memory leak is gone with this change by running https://github.com/naruaway-sandbox/fast-refresh-hmr-memory-leak-demo with the change. I am not sure whether new tests are needed but my concern is to accidentally break Fast Refresh behavior somehow. I believe we have enough existing test cases 🙏 and I also tested manually. |
||
---|---|---|
.. | ||
internal | ||
loader.ts | ||
package.json | ||
ReactRefreshWebpackPlugin.ts | ||
README.md | ||
runtime.ts | ||
tsconfig.json |
@next/react-refresh-utils
This is an experimental package that provides utilities for React Refresh.
Its API is not stable as that of Next.js, nor does it follow semver rules.
Use it at your own risk.
Usage
All entrypoints below must wired into your build tooling for this to work.