Styled-components: createGlobalStyle creates memory leak in Next.js

Created on 14 Feb 2020  ·  42Comments  ·  Source: styled-components/styled-components

Environment

Binaries:

  • Node: 13.7.0 - ~/.nvm/versions/node/v13.7.0/bin/node
  • Yarn: 1.21.1 - /usr/local/bin/yarn
  • npm: 6.13.6 - ~/.nvm/versions/node/v13.7.0/bin/npm

    npmPackages:

  • babel-plugin-styled-components: ^1.10.7 => 1.10.6

  • styled-components: ^5.0.1 => 5.0.1

Problem

We are using styled-components and Next.js (7.2.1) and we have experienced memory leaks in our app for some time, so I started to investigate it, in the process I found other issues here about:

  • using the css helper when composing styling partials to be interpolated into a styled component
  • not to use @import inside createGlobalStyle
  • not dynamically create components

So I went through the whole app making sure to avoid these. I deployed a new version but the memory leak was still present. As seen on the graph below:
Skjermbilde 2020-02-14 19 49 28

After inspecting the node server I found out it was createGlobalStyle in our _app.js (Next.js file) that caused the memory to rise. In the createGlobalStyle we used fontFace/normalize from polished), and around 50 other lines of reset css (nothing special).

Removing createGlobalStyle solved the memory leak (or at least reduced to a minimum).
See the graph below:
Skjermbilde 2020-02-14 19 50 55

Did we use createGlobalStylewrong or do someone have some insight to this?

needs more info

Most helpful comment

So I'm giving up on properly solving this issue, I can't figure out how to pass context in my particular case with getDataFromTree(<Tree />, ctx), because I'm not sure where to even take it. But issue is definitely as I described here. I still wonder why masterSheet exists, because it's singleton which is never cleaned up, at least from my understanding.

Nevertheless I have found a workaround to mitigate this issue:

            await getDataFromTree(
              // workaround for memory leak, see https://github.com/styled-components/styled-components/issues/3022
              <StyleSheetManager sheet={new ServerStyleSheet().instance}>
                <AppTree {...props} />
              </StyleSheetManager>
            )

Just wrapping it with StyleManager will make it use new StyleSheet every time. Not sure if there will be any harmful side effects here.

All 42 comments

in our next.js project, we can only use one createGlobalStyle, other global styles is replaced with next.js