react-jsonschema-form icon indicating copy to clipboard operation
react-jsonschema-form copied to clipboard

Medium sized schema becomes uncomfortably laggy to type in inputs.

Open adjenks opened this issue 1 year ago • 9 comments

Prerequisites

What theme are you using?

core

Version

5.x

Current Behavior

It's super slow with somewhat large schema with some conditional sections. Typing is extremely laggy.

It appears to run some deep schema merge functions after every keystroke, can I prevent this?

Expected Behavior

Negligible lag.

Steps To Reproduce

Use the following schema to build a form:

var schema = {
  "title": "Demo schema",
  "type": "object",
  "required": [
    "redacted1",
    "redacted2",
    "redacted3",
    "redacted4",
    "redacted5",
    "redacted6"
  ],
  "dependentRequired": {},
  "allOf": [
    {
      "if": {
        "properties": {
          "redacted18": {
            "const": false
          }
        }
      },
      "then": {
        "required": []
      },
      "else": {
        "required": [
          "redacted6"
        ]
      }
    }
  ],
  "properties": {
    "redacted1": {
      "type": "string"
    },
    "redacted2": {
      "type": "string",
      "format": "date"
    },
    "redacted3": {
      "type": "string"
    },
    "redacted4": {
      "type": "string",
      "oneOf": [
        {
          "const": "red1"
        },
        {
          "const": "red2"
        }
      ]
    },
    "total_redacted5": {
      "type": "integer"
    },
    "redacted6a": {
      "type": "string"
    },
    "redacted7": {
      "type": "string"
    },
    "redacted8": {
      "type": "string"
    },
    "redacted9": {
      "type": "string"
    },
    "redacted10": {
      "type": "object",
      "readOnly": true,
      "properties": {
        "red1": {
          "type": "string"
        },
        "red2": {
          "type": "string"
        },
        "red3": {
          "type": "string"
        }
      }
    },
    "redacted11": {
      "type": "integer"
    },
    "redacted12": {
      "type": "string"
    },
    "redacted13": {
      "type": "string",
      "format": "date"
    },
    "redacted14": {
      "type": "array",
      "items": {
        "allOf": [
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "title": "Type",
                "oneOf": [
                  {
                    "const": "asdf1"
                  },
                  {
                    "const": "asdf2"
                  },
                  {
                    "const": "asdf3"
                  },
                  {
                    "const": "asdf4"
                  },
                  {
                    "const": "asdf5"
                  },
                  {
                    "const": "asdf6"
                  },
                  {
                    "const": "asdf7"
                  },
                  {
                    "const": "asdf8"
                  },
                  {
                    "const": "asdf9"
                  },
                  {
                    "const": "asdf10"
                  },
                  {
                    "const": "asdf11"
                  },
                  {
                    "const": "asdf12"
                  },
                  {
                    "const": "asdf13"
                  },
                  {
                    "const": "asdf14"
                  },
                  {
                    "const": "asdf15"
                  },
                  {
                    "const": "asdf16"
                  },
                  {
                    "const": "asdf17"
                  },
                  {
                    "const": "asdf18"
                  },
                  {
                    "const": "asdf19"
                  },
                  {
                    "const": "asdf20"
                  },
                  {
                    "const": "asdf21"
                  },
                  {
                    "const": "asdf22"
                  },
                  {
                    "const": "asdf23"
                  },
                  {
                    "const": "asdf24"
                  },
                  {
                    "const": "asdf25"
                  },
                  {
                    "const": "other"
                  }
                ]
              },
              "redacted15": {
                "type": "integer"
              }
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "other"
                }
              }
            },
            "then": {
              "properties": {
                "description": {
                  "type": "string"
                }
              },
              "required": [
                "description"
              ]
            },
            "else": {
              "properties": {}
            }
          }
        ]
      }
    },
    "redacted16": {
      "type": "object",
      "properties": {
        "completed": {
          "type": "boolean"
        },
        "date": {
          "type": "string",
          "format": "date"
        },
        "redacted17": {
          "type": "boolean",
          "oneOf": [
            {
              "const": null,
              "title": "Unknown"
            },
            {
              "const": true,
              "title": "True"
            },
            {
              "const": false,
              "title": "False"
            }
          ]
        }
      }
    },
    "redacted18": {
      "type": "boolean",
      "oneOf": [
        {
          "const": null,
          "title": "Unknown"
        },
        {
          "const": true,
          "title": "True"
        },
        {
          "const": false,
          "title": "False"
        }
      ]
    },
    "redacted6": {
      "type": "string",
      "format": "date"
    },
    "redacted19": {
      "type": "boolean"
    },
    "redacted20": {
      "type": "string",
      "format": "date"
    },
    "redacted21": {
      "type": "boolean"
    },
    "redacted22": {
      "type": "boolean"
    },
    "redacted23": {
      "type": "boolean"
    },
    "redacted24": {
      "type": "integer"
    },
    "redacted25": {
      "type": "integer"
    },
    "redacted26": {
      "type": "string",
      "format": "date"
    },
    "redacted27": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "redacted28": {
            "disabled": true,
            "type": "integer"
          },
          "redacted29": {
            "type": "string",
            "readOnly": true
          },
          "redacted30": {
            "type": "boolean"
          },
          "redacted31": {
            "type": "integer"
          },
          "redacted32": {
            "type": "string"
          },
          "redacted33": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "redacted34": {
                  "type": "string",
                  "readOnly": true,
                  "examples": [
                    "1"
                  ]
                },
                "redacted35": {
                  "type": "string",
                  "readOnly": true,
                  "examples": [
                    "TNT"
                  ]
                },
                "redacted3_code": {
                  "type": "string",
                  "examples": [
                    "820"
                  ]
                },
                "redacted3_en": {
                  "type": "string",
                  "examples": [
                    "ASDFASDFASDF"
                  ]
                },
                "redacted3_fr": {
                  "type": "string",
                  "examples": [
                    "ASDFASDFASDF"
                  ]
                },
                "redacted36": {
                  "type": "string",
                  "examples": [
                    "1"
                  ]
                },
                "redacted37": {
                  "type": "string",
                  "examples": [
                    "14897838"
                  ]
                },
                "redacted38": {
                  "type": "string",
                  "examples": [
                    "9821542"
                  ]
                },
                "redacted39": {
                  "type": "string",
                  "examples": [
                    "4"
                  ]
                },
                "redacted40": {
                  "type": "string",
                  "examples": [
                    "2003"
                  ]
                },
                "redacted41": {
                  "type": "string",
                  "examples": [
                    "AS2"
                  ]
                },
                "redacted42": {
                  "type": "string",
                  "examples": [
                    ""
                  ]
                },
                "redacted43": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "asdf1": {
                        "type": "string",
                        "examples": [
                          "1"
                        ]
                      },
                      "asdf2": {
                        "type": "string",
                        "examples": [
                          "5693"
                        ]
                      },
                      "asdf3": {
                        "type": "string",
                        "examples": [
                          "asdfasdfasdf"
                        ]
                      },
                      "asdf4": {
                        "type": "string",
                        "examples": [
                          "6"
                        ]
                      },
                      "asdf5": {
                        "type": "string",
                        "examples": [
                          "Y"
                        ]
                      },
                      "asdf6": {
                        "type": "string",
                        "examples": [
                          "C"
                        ]
                      },
                      "abc_asdf": {
                        "type": "string",
                        "examples": [
                          "PR"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "version": {
    "title": "Version",
    "type": "string",
    "default": "1.0"
  },
  "$defs": {
    "thingy": {
      "type": "string"
    }
  }
}

Environment

Tested in Chrome and Firefox on Windows

Anything else?

image

The call stack you see in the image occurs on each keystroke and brings my cpu up to 90% each time, there is an average jank/lag of 200ms which makes typing very uncomfortable.

The lag is similar when you paste the schema into the playground, but the playground is slightly more responsive ~150ms instead of 200.

Every yellow bump on the graph is a keystroke and is 90% of my CPU for a brief moment.

The schema is not done yet and will be bigger but I'm afraid it will become completely unusable.

adjenks avatar Jun 02 '23 00:06 adjenks

I have a similar experience with large schemes, especially when using the Form from the MUI theme @rjsf/mui and have many properties arrays with nested properties.

import Form from '@rjsf/mui'; <Form schema={mySchema} formData={myFormData} validator={myValidator} />

Setting myFormData is extremly slow and blocks UI (when need to render Form) for 5-10 seconds.

When I use Form from @rjsf/core import Form from '@rjsf/core'; Everything is fine and works perfectly.

loodsite avatar Jun 03 '23 14:06 loodsite

Unfortunately @loodsite , the schema I've presented still lags considerably for me even using the rjsf/core Form component. It's slightly faster, maybe 10 or 20% faster, but there is still a second or more of keyboard lag when typing a long sentence in a text field. Pasting a long string is considerably faster than typing it because it seems to re-render everything at each keystroke.

adjenks avatar Jun 06 '23 19:06 adjenks

@adjenks Did you solve it? I'm also having performance issues

xyy7260 avatar Jun 26 '23 06:06 xyy7260

@xyy7260, No, I just abandoned this library and built my form without it. Hopefully in the future I can come back here and it will work more efficiently.

adjenks avatar Jun 28 '23 17:06 adjenks

I'm experiencing these issues, too. We're currently considering dropping the use of the lib because of this. It would be awesome if this deep-down merges could be prevented.

ivogonzalvez avatar Oct 20 '23 15:10 ivogonzalvez

The same here. I feel stuck at this point, especially when we thought we were settled with this library in our product.

I have also noticed that on each keystroke the whole schema gets evaluated/compiled.

I would expect this to be the case only with subschemas that depend on the particular field that has been edited.

I have tried with:

liveOmit={true}
omitExtraData={true}

No change. I am using @rjfs/mui

Help/advice from the maintainers is much appreciated.

magaton avatar Oct 20 '23 17:10 magaton

Same exact issue here. Even with validation turned off, typing in a keystroke to any input in the form with a complex JSON schema results in a 2-4 second delay before the character is rendered in the input.

It would be nice if there was a way to only compute the json form fields on the first render, and then the json schema would only be evaluated on submit if live validation is turned off.

mnannola avatar Jan 23 '24 14:01 mnannola

Are there any workarounds for this? We have a large schema that was performant in v4, but after upgrading to v5 it's VERY laggy

joncarlson avatar Feb 13 '24 17:02 joncarlson

I think it was a maintainer who added the if-then-else label to this issue while he was adding the performance label. We noticed that our scheme was using this construct, so we got excited, but we removed it and it did not fix our performance issue.

burnettk avatar May 20 '24 18:05 burnettk