swagger-api / swagger-api/swagger-ui
Rendering Swagger UI in a React app causes a memory leak
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 29k
- Forks
- 9.3k
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 25
Description
Q&A (please complete the following information)
- OS: Windows 10
- Browser: Chrome 70.0.3538.110
- Version: 70.0.3538.110
- Method of installation:
- Swagger-UI version: Any recent
- Swagger/OpenAPI version: [e.g. Swagger 2.0, OpenAPI 3.0] Not relevant
Content & configuration
Conditionally rendering the Swagger UI in a React application when rendering the Swagger UI per the recommendations in https://github.com/swagger-api/swagger-ui/issues/3000 and per the sample repo https://github.com/shockey/swagger-ui-cra for Create React App causes a memory leak.
Conditionally rendering just the Swagger UI's root div rather than a component that creates the Swagger UI instance in ComponentDidMount is not a viable alternative because on a subsequent re-render, the Swagger UI will not be displayed (which is expected).
This is a pretty common use case in React so it seems like there should be either (a) a way for the parent app to clean up the Swagger UI's memory, perhaps in componentWillUnmount or (b) The Swagger UI should handle this case itself somehow
I've forked the demo of using the Swagger UI with Create React App and added a toggle button to demo the memory leak here:
https://github.com/linelson/swagger-ui-cra/blob/master/src/App.js
Example Swagger/OpenAPI definition:
The default petstore definition is sufficient.
Swagger-UI configuration options:
See https://github.com/linelson/swagger-ui-cra/blob/master/src/App.js
Describe the bug you're encountering
Conditionally rendering the Swagger UI (or the Swagger Editor) in the context of a simple React application creates a memory leak.
To reproduce...
See the screenshots below for examples.
Repo: https://github.com/linelson/swagger-ui-cra
Steps to reproduce the behavior with Redux Dev Tools:
- Clone the linked repo and run the app
- Have Redux dev tools installed and look at the Swagger UI state.
- Click the 'Toggle Swagger UI' button a couple of times
- Look at the Swagger UI state in Redux dev tools. Note that there are now
ninstances of the Swagger UI redux state, wherenis the number of times the 'Toggle Swagger UI' button was clicked.
Steps to reproduce the behavior with Chrome dev tools:
- Clone the linked repo and run the app
- Take a memory snapshot before clicking anything on the app page
- Click the 'Toggle Swagger UI' button a couple of times
- Take another memory snapshot
- Note the increase in memory use
Expected behavior
No memory leak, per https://github.com/swagger-api/swagger-ui/issues/3000#issuecomment-300349616 😛
Screenshots
Every time the 'Toggle Show UI' button is clicked another redux state is initialized (and never cleaned up):

Clicking the button repeatedly also results in a pretty dramatic memory increase using chrome's memory snapshot:

Snapshot 3 was taken on a clean refresh of the page. Snapshot 4 was taken after clicking the 'Toggle Swagger UI' button a couple of times.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reproduction in src/App.js from the linked swagger-ui-cra repository, focusing on the component mounted in ComponentDidMount and the Toggle Swagger UI button. Use Redux DevTools and Chrome memory snapshots while toggling the UI to confirm that Redux state instances accumulate. Done means repeated mounting and unmounting no longer leaves additional Swagger UI state or memory behind.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100