swagger-api / swagger-api/swagger-ui

Rendering Swagger UI in a React app causes a memory leak

Open
#5,092 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

cat: performance P2 type: enhancement
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:

  1. Clone the linked repo and run the app
  2. Have Redux dev tools installed and look at the Swagger UI state.
  3. Click the 'Toggle Swagger UI' button a couple of times
  4. Look at the Swagger UI state in Redux dev tools. Note that there are now n instances of the Swagger UI redux state, where n is the number of times the 'Toggle Swagger UI' button was clicked.

Steps to reproduce the behavior with Chrome dev tools:

  1. Clone the linked repo and run the app
  2. Take a memory snapshot before clicking anything on the app page
  3. Click the 'Toggle Swagger UI' button a couple of times
  4. Take another memory snapshot
  5. 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):
image

Clicking the button repeatedly also results in a pretty dramatic memory increase using chrome's memory snapshot:
image
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.