Application size and performance

I really like the architecture of JSON Forms. The way it does the UI schema is great! I have some experience working on a similar project that has since been stopped because we ran into several problems. From a design perspective I think JSON Forms addresses the issues in defining the form. In the long term it would be very helpful to have a visual form builder so that less-technical people would design a form without coding. That can wait though!

The main issue I have concerns about is being able to use this for a site that needs to work on low-end phones with lower-speed connections. The seed application is 1.3 megabytes, which takes a long time to download and parse. Even the gzip size is over 300KB, and it’s one big file so there is no opportunity to load just a few things and do the rest later.

Is this something you’d be willing to work on with me? I’ve attached the output from a run of source-map-explorer on the seed app. A few things stick out immediately that we can probably fix:

  • Moment is being used for date manipulation, and it’s a very large monolithic package. Switching to date-fns would save quite a bit of space, if there aren’t too many dependencies on moment quirks.
  • The js-yaml package is pulling in an entire Esprima parser! Does the app really need to parse YAML files at runtime? If it needs to process YAML files, could they be preprocessed to JSON perhaps?
  • We’re getting two copies of lodash, one appears to be modules and the other monolithic.
  • Since everything is parsed and computed at runtime, the app is bundling everything that any schema might use. Some sort of static build step would really help to reduce the bundle size.
  • My experience with react-jsonschema-form was that any change (even a keypress) recalculated the entire schema which can make for a very slow app. It looks like the same may happen with JSON Forms? If it was possible to calculate the dependencies every field has and only recompute a field if one of its dependent fields changes, that would save a huge amount of time.

Those are the things I can see up front. As far as quick fixes, switching out Moment and hunting down the redundant lodash might be the easiest one for me to start with. Let me know if you’re interested!

Hi @dmethvin-gov, thank you very much for the suggestions and detailed analysis. The overall size of JSON Forms builds is also pretty high on our priority list and we are currently very active in improving the current state of things.

Moment is being used for date manipulation, and it’s a very large monolithic package. Switching to date-fns would save quite a bit of space, if there aren’t too many dependencies on moment quirks

Good find. We also realized this and recently removed Moment from our dependencies. Instead we switched to the much smaller dayjs which covers all our needs. Users can then select which locales they actually need.

The js-yaml package is pulling in an entire Esprima parser! Does the app really need to parse YAML files at runtime? If it needs to process YAML files, could they be preprocessed to JSON perhaps?

js-yaml came in by the json-schema-ref-parser dependency. This dependency also had a lot of other disadvantages, so we also removed it from JSON Forms.

We’re getting two copies of lodash, one appears to be modules and the other monolithic.

Yes this is bad. The problem here is that at the moment we publish our modules as commonjs which does not support tree shaking. We are currently working on switching to ESM modules as part of our 3.0 release, so I expect that after we complete this there should only be the lodash modules left which are actually used.

My experience with react-jsonschema-form was that any change (even a keypress) recalculated the entire schema which can make for a very slow app. It looks like the same may happen with JSON Forms? If it was possible to calculate the dependencies every field has and only recompute a field if one of its dependent fields changes, that would save a huge amount of time.

This is a problem which most form renderers / generators have which are based on JSON Schema. The problem is that the JSON Schema validation support is pretty complex, so it’s hard to calculate dependencies beforehand. I’m not sure whether we want to add some special support here in JSON Forms or rather wait until AJV offers something in this direction. I also noted this on the JSON Schema thread regarding a form vocabulary special interest group

To improve the current state of things we introduced debouncing support for fast-changing inputs like texts. This vastly improves the UX experience.

Since everything is parsed and computed at runtime, the app is bundling everything that any schema might use. Some sort of static build step would really help to reduce the bundle size.

Very interesting suggestion. This could then be similar to the static AJV standalone builds by which you can also precompute the required validator. This makes sense if you know the JSON Schema, UI Schema etc. beforehand. Our main focus is on use cases where this is not the case so we don’t have this on our agenda at the moment. Do you have experience with this use case? What changes do you expect would need to be done on JSON Forms?

All of the improvements mentioned above are part of the @next stream. Just today we made the 3.0.0-alpha.2 release by which you can check out the changes yourself.

As you can see we are very interested in this topic, so if you have further suggestions, analysis or even contributions to improve bundle size and the UX look and feel then they are very welcome :wink:

It sounds like most of the size issues either have been fixed or are being addressed right now. Awesome! I will try to pull down the version 3 alpha and check it out.

I’m not sure whether we want to add some special support here in JSON Forms or rather wait until AJV offers something in this direction. I also noted this on the JSON Schema thread regarding a form vocabulary special interest group

It seems like all the current schema validators are expected to be used in a batch/bulk mode where the whole schema is analyzed. That’s bad for performance in a case like form validation. However, if there are no dependencies for an item (by far the most common case) it should be possible to validate only the sub-schema against its subset of the data?

This makes sense if you know the JSON Schema, UI Schema etc. beforehand. Our main focus is on use cases where this is not the case so we don’t have this on our agenda at the moment. Do you have experience with this use case? What changes do you expect would need to be done on JSON Forms?

In most of the cases where I have created forms, I think it would be possible to determine the union of all possibly used controls and validations in a static compile step by processing all the JSON schema and UI schema that were being used. That is, if I don’t have any date inputs I don’t need to pull in any of the date input controls or validations.

One complication in JSON Forms is that the ranking of controls is done by a procedural function so it could return any rank including a random number that varied at runtime. That seems unlikely and if it’s really rare it would be easiest to document that such cases would not be eligible to use static analysis.

I haven’t looked at the code in detail yet, so it sounds like I should do that to see how crazy those ideas are. :smiley:

In the long term it would be very helpful to have a visual form builder so that less-technical people would design a form without coding. That can wait though

I overlooked this in my first response. You might be interested in the JSON Forms editor (repo) which allows to visually create and modify a UI Schema for a JSON Schema.