cssinjs / cssinjs/jss

`react-jss` dynamic rules memory leak in strict mode

Open
#1,648 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
JavaScript
Stars
7.1k
Forks
386
PR merge metrics
No merged PRs in 30d

Description

__Expected behavior:__
Unreferenced style rules should be properly removed after un-mounting all associated components instances.

__Describe the bug:__
When React's strict mode is enabled, dynamic rules are not properly removed after un-mounting components, probably because of strict mode's double render (rule keys gets shifted during second render, probably because React Hooks best practices were not followed).

The app ultimately becomes unresponsive.

__Reproduction:__

https://codesandbox.io/s/happy-joliot-pmmq4d

It is sufficient to mount and un-mount a component with dynamic styles in any React application using strict mode and count the number of attached styles rules.

1. Clone [this simple reproduction repo](https://github.com/ernestostifano/jss-playground).
2. Checkout this branch: `issue/react-jss-no-dynamic-remove`
3. Run `yarn start`
4. Alternately click on `Component A` and `Component B` buttons and see how style rules count increases.
5. Remove `` from `./src/app.js` and repeat step `4`. No more leak.

**Note:** If a custom ID generator is added to print generated classnames, it can be seen how keys increase twice because of strict mode's double render.

__Versions (please complete the following information):__
- jss: `10.10.0`
- Browser: `Chrome`, `Firefox`, `Safari` and `Edge` (latest versions at the time of submission)
- OS: `macOS 13.4`

__Managing expectations:__
**I think this is an important bug because it can be easily reproduced and ultimately makes apps unresponsive during development. Also, it was not that simple to pinpoint the source of the memory leak. Should not be that difficult to fix. I would be happy to work on the fix if someone gives me proper context.**

__Potentially related issues:__
- https://github.com/cssinjs/jss/issues/1536
- https://github.com/cssinjs/jss/issues/1616
- https://github.com/cssinjs/jss/issues/1026
- https://github.com/cssinjs/jss/issues/1360

Contributor guide

Open the contributing guide

Research direction

Start with the linked jss-playground reproduction on branch issue/react-jss-no-dynamic-remove, run yarn start, and inspect src/app.js with StrictMode enabled. Reproduce the alternating Component A and Component B mounts, then trace the dynamic-rule lifecycle in JSS; done means unmounting all instances no longer increases the attached style-rule count.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
frontend, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.