Bug report
Forms with large amount of fields (>100, as is often the case with arrays and nested subforms) take a long time to render.
The slowdown is most notable on initial render, where the form can take up to 10s of seconds to render initially. Renders after that are usually fast enough, but not super-fast, causing some input delay.
If I run the Chrome devtools, I can see that the initial render slowdown is caused by notifySubscriber taking more and more time as more fields are being registered, making me think that notifySubscriber is not O(1) but O(fields already registered).
I'm building forms recursively from a JSON schema, maybe react-final-form is not the right tool for the job since all fields are know in advance, so I don't need the notifySubscriber at all?
Speedy Gonzales!
I'll try and put together an example soon!
final-form 4.6.1
final-form-arrays 1.0.4
react 16.3.2
react-final-form 3.4.2
react-final-form-arrays 1.0.4
See also #230.
Here's a profile I've made with Google Chrome, you should be able to load that as well.
profile.json.txt
I managed to optimize this by limiting the subscriptions and pausing the validation but I still have an irreducible problem during the unmount, @erikras do you have an idea maybe?
Note that I am seeing validations run on unmount - while not necessarily the same case it is related to performance of large or complex forms with validations #408
Maybe it's better pass a validateOnBlur prop, I didn't try it but i think it could be effective
The validation has to run whenever a new field is added, but on initial render, there is a mechanism that _should_ (perhaps it's broken here?) pause all validation from running until the entire form has been rendered (i.e. all fields registered) and then runs validation. It'll require some investigation...
I'm having the same performance issue when dealing with large forms.
I created an example to show the re-render issue: https://codesandbox.io/embed/react-final-form-simple-example-bsbtj
Any field change will cause the whole form re-render, deep into every field.
I tried to apply validateOnBlur to the <Form /> level, but it doesn't reduce the frequency of re-render. Every key down will trigger the whole form re-render.
Is this an expected behavior? Or the way I'm using it is wrong.
Any ideas? Thanks,
@lazurey Yep, that's by design because it's easier out of the box and isn't a problem for most (small) forms. To fine tune the rerendering, you've gotta put a subscription on the <Form>. See the 馃挜 Performance Optimization Through Subscriptions 馃挜 example.
I have created a vue version of final-form, I had this issue on field arrays with thousand of fields but i had a trick , I disabled the validations in first render and then resume them with setTimeout(fn,0) and we are good now, I don't know this implemented in react version or no.
Another trick is i created stateful wrapper around the fields and used debounce function.
The subscriptions didn't help me,
@erikras
Twitter thread about the "thousand field problem". @alirezavalizade, I don't know how easy it would be to throw your thing in there, but if it's doable, I'd love to have it.
Also, if you're not talking about vue-final-form, I'd be happy to link to your thing on the FF readme.
BTW, to the original poster, @romeovs, RFFv5 (and now v6) made a significant change, allowed by the glory of hooks, to how field-level validation is done on first render. This whole thing might be okay now. 馃檹
We didn't publish it yet, but we are using it in our company, I'll make a pull request soon.
@erikras how can it be controlled with hooks?
That's still an issue.
You might be interested in to use this library (disclaimer: I am an author of the project). It is based on hooks and solves the issue of large form states. Here is the demo of a form with 5000 fields: state update on every keystroke without any performance lag. It supports validation too and you can write other custom plugins.
@alirezavalizade any updates on that pull request? I'm facing this problem as well :(
Most helpful comment
We didn't publish it yet, but we are using it in our company, I'll make a pull request soon.