-
Notifications
You must be signed in to change notification settings - Fork 9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UI crashes on complex OpenAPI documents #9513
Comments
Am also experiencing the same, Any fix/walk-around ? UPDATE: 13th Feb 2024 |
I can confirm. This is very reproducible. |
Investigating this issue within Swagger Client, I found out that the resolve mechanism executes for a long time due to the complexity of the specification with the nested references. The specification should eventually be resolved but the operations take too long. Because of this SwaggerUI will freeze. I tried breaking out of the traversal early by creating and setting a maximum count of it to a 1000 for each run of the plugins. I broke out of the execution here https://github.com/swagger-api/swagger-js/blob/f00b527fd71f46ccf1a4ae14853edc5452160b04/src/specmap/index.js#L108 and here https://github.com/swagger-api/swagger-js/blob/f00b527fd71f46ccf1a4ae14853edc5452160b04/src/specmap/index.js#L137 if the limit was reached. This allowed the specification to be partially resolved and loaded in SwaggerUI, although rendering slowly. Unfortunately, as we don’t resolve everything, components looked like this: ![]() ![]() The missing values are unresolved, for example
and
Perhaps we could render these unresolved definitions with reference strings but resolving everything is not possible at the moment. |
This change eliminates the infinite recursion when handling cycles during resolution. Refs swagger-api/swagger-ui#9513
The crashing issue was addressed in swagger-api/swagger-js#3380, released as https://github.com/swagger-api/swagger-js/releases/tag/v3.25.3. As it turned out, the complex specification was being eventually resolved, but the operations took too long due to the nested definitions. To fix this, we limited the maximum traversal depth for each run of the plugins. This allows us to get a partially resolved specification, which has to be resolved further in Swagger UI. |
Rendering schemas not resolved by Swagger Client addressed in #9629. |
This still fails on the original example given in the issue description. Steps:
Please reopen the issue! |
Hi @pavelkornev, There are number of issues that SwaggerUI is having with https://api.sap.com/odata/1.0/catalog.svc/APIContent.APIs('SAP_ICSM_StudyService')/$value?type=json SizeThe original definition is almost 2MB in size. This alone makes it challenging for SwaggerUI to deal with it. ComplexityThe complexity of this definition is extreme. By complexity I mean how Schema Objects are referenced and used. SwaggerUI uses SwaggerClient to dereference the definition in a special way - it tries to eliminate all the cycles (circular references) so that SwaggerUI can expect that no cycles are present when rendering. Cycles (circular references)To eliminate cycles, we use SwaggerClient legacy mechanism for OpenAPI 2.0 and 3.0.x. We use ApiDOM for OpenAPI 3.1.0. Given that you definition is in OpenAPI 3.0.x, SwaggerClient uses legacy mechanism which cannot cope with tracking the references on such a complex definition; we've addressed that in 7300e6c where we stop the dereferencing at some point in forced way. Now ApiDOM can correctly dereference your definition and eliminate all cycles, but it takes around 25 seconds to do so (because of the definition complexity). Without the cycle detection (circular=ignore), ApiDOM can dereference the definition under 1 second. ApiDOM in future will take over all the dereferencing in SwaggerClient, so it needs to utilize a solution similiar in 7300e6c. In ApiDOM it's possible to interrupt the traversal in safe way without exposing the incompletely dereferenced definition for cycle occurence. RenderingSwaggerUI unfortunately uses Immutable.js for it's redux store. This means that every piece of JavaScript data that hits the redux store (and state respectively) needs to be serialized into immutable structure and then when it hits the component is (somethimes) deserialized againt to JavaScript value. Now when you click on to expand the operation, all it's data get dereferenced (+ cycle elimination) which creates extremely large data in browser memory. This data needs to be then serialized into immutable structure. And this is where the browser crash happens - trying to serialize the deferenced operation into redux store. Even when we would factor our the immutable from the equation, we still need to generate example values for your JSON schemas. That would be slow as well, again given the definition complexity. This is just analysis of what is currently causing the performance issue on this definition (and others with similiar complexity). It's not one thing, it's a combination of multiple issues. |
I've did additional measurements about Immutable.js serialization speed and memory footprint on this definition. I've used Node.js a following APIs for the measurement: node:perf_hooks
performance.now() Using pure JavaScript (without Immutable.js):Memory consumption:
Serialization time:
Using Immutable.js:Memory consumption:
Serialization time:
|
@char0n would you consider dropping Immutable.js if it causes such a big memory consumption? |
Yes it's a long term plan. But it basically means rewriting the entire SwaggerUI. SwaggerUI basically consists of selectors, reducers, actions and components and Immutable.js is the interface that all of these bind to. After we've removed Immutable.js we still have problem of dereferencing lasting 25 seconds on your definition. We can solve that by hard stopping the dereferencing at certain level. Then the next issue is probably going to be example generation from JSON Schemas. Given the extreme schema complexity, this problem can be totally avoided by defining one of the JSON Schema keywords: |
I have a json swagger that is 3.5 mb large. How can I improve it ? |
Q&A (please complete the following information)
Content & configuration
When rendering a complex OpenAPI document, UI comes unresponsive first with the following browser dialog, and eventually crashes later:



Example Swagger/OpenAPI definition:
https://api.sap.com/odata/1.0/catalog.svc/APIContent.APIs('SAP_ICSM_StudyService')/$value?type=json
Describe the bug you're encountering
To reproduce...
Steps to reproduce the behavior:
Expected behavior
UI doesn't crash.
The text was updated successfully, but these errors were encountered: