styled-components: SSR Memory Leak SC - 3.2.3
Environment
System:
- OS: Linux 3.13
- CPU: x64 Intel® Xeon® CPU E5-2666 v3 @ 2.90GHz
- Free Memory: 723.59 MB
- Total Memory: 7.30 GB
- Shell: ¯_(ツ)_/¯
Binaries:
- Node: 8.4.0
- Yarn: 0.27.5
- npm: 5.3.0
- Watchman: Not Found
npmPackages:
babel-plugin-styled-components:
- wanted: ~1.5.0
- installed: 1.5.0
styled-components:
- wanted: 3.2.3
- installed: 3.2.3
Reproduction
Reproduction is a little hard. We have relatively large Next.js application with a large amount of styles. Running here - https://weedmaps.com/deals. This behavior doesn’t seem to be present on smaller example applications
Steps to reproduce
Using the same method for re-hrydration as the next.js examples -
static async getInitialProps(context) {
const { renderPage, req } = context;
const sheet = new ServerStyleSheet();
const page = renderPage(App => props =>
sheet.collectStyles(<App {...props} />),
);
// Flush Styled Components
const styleTags = sheet.getStyleElement();
return {
...page,
styleTags,
};
}
We are seeing accumulation of tags in the tagMap in the master StyleSheet. Here is an snap of the captured heap.

I can provide the actual Heapdump if it is useful, but I don’t want to attach it here. This leak is slower in 3.2.3, after the fixes were applied, but it is still present
Expected Behavior
The master StyleSheet should not retain tags across requests.
Actual Behavior
Seeing slow and steady memory leak in the StyleSheet.master.tagMap. After a time we are seeing hundreds of thousands of retained tags.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 1
- Comments: 20 (6 by maintainers)
@kitten I have tracked this down and we are creating dynamic components at runtime. This is causing the server render to not be deterministic across page refreshes. I would imagine this is causing the tagMap to grow indefinitely as well. Closing this, as we can fix on our side. Thanks for your work and patience
We ran into similar issues were our server memory kept increasing over time, which caused several pods to crash but also performance issues : as stated above, response time is directly linked to the
StyleSheet(tagMap) size.Here is the problem :
styled-components is responsible for calling
sheet.complete()when the rendering part is done, cleaning the memory up.Nevertheless, if something bad happens during the rendering process - and bad things always happen - exceptions may be thrown, and they get nicely caught by the server which will log stuff and send a 4xx or 5xx HTTP error back… In that case,
sheet.complete()is not called, resulting in a potentially huge leak.This is how we fixed it, I think you should update all SSR examples accordingly :
@maxparelius yes it would be a Styled Component that is created inside something that is called dynamically (like a React Component) e.g.
vs.
@bringking regarding that code snippet, what is it being used for, since I thought we’re talking about an SSR leak. Maybe I misunderstood parts of your issue description? 😅
Btw,
HTMLTag#sheetwon’t work on all browsers; Not related but since I’m already seeing this, I might as well point it out 😄 https://github.com/styled-components/styled-components/blob/master/src/utils/insertRuleHelpers.js#L7-L21