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

Performance problem with Field or FieldArray during registration and unregistration fields

Open marrkeri opened this issue 5 years ago • 10 comments

Are you submitting a bug report or a feature request?

Bug

What is the current behavior?

Check the sandbox below and click on Initialize button and then on Reset. Slow registration and unregistration bigger amount of fields(500 rows with 3 columns = 1500 fields). I have used subscription only to 'value' and 'submitting'. I haven't provided any validation yet but keep in mind that it will be also included for the subscription. I have tried also Field instead of FieldArray. In the sandbox, it is included as a comment.

What is the expected behavior?

Better performance.

Sandbox Link

https://codesandbox.io/s/youthful-morning-msnpk https://msnpk.csb.app/

What's your environment?

"final-form": "^4.18.5",
"final-form-arrays": "^3.0.1",
"react": "16.8.6",
"react-dom": "16.8.6",
"react-scripts": "3.0.1",
"react-final-form": "^6.3.0",
"react-final-form-arrays": "^3.1.1"

Other information

<Form debug={console.log}> During initialization produce lot of records image

I really love the final form. I have used redux-form, formik, react hook form and nothing is so powerful than your library. Just this performance makes me crazy. Thank you for help.

marrkeri avatar Nov 03 '19 20:11 marrkeri

This issue is a major blocker for my current project. Is anyone able to suggest a workaround? My project has up to ~200 fields on the page, and the unmounting time is critical.

nj314 avatar Nov 14 '19 00:11 nj314

It seems to me the notification to listeners happen per field registration and the field registration happens twice in useField hook, once for setting up the initial state, and second time for subscribing to the future changes.

I've tried to to make the registration only happen once and manually initialize the state, which did make a noticeable performance improvements. https://github.com/ryank109/final-form/commit/0f6b989209cbee4cf7646b98a5d70cbbc39a3f52 https://github.com/ryank109/react-final-form/commit/0871e203a33f54110d46e03211885a721177d7f4

And I think there was an issue regarding removing/hiding parts of the form removes the error/touched/value state of the fields too (couldn't find it), which above will also solve. Above changes never unregister the fields and (i'm hoping) the form will clean them when the form itself is unmounted. So I guess this might have to be an opt-in thing, if you never want to unregister when the field component is unmounted?

ryank109 avatar Nov 21 '19 04:11 ryank109

Any updates on this?

joni3k avatar Jan 30 '20 12:01 joni3k

@erikras Any updates?

marrkeri avatar Apr 22 '20 10:04 marrkeri

Also in the example given, when you type into the fields it is noticeably slow. This is a problem that I have also experienced with Formik and redux-form... more than 30 fields and it becomes slow.

coultonluke avatar Nov 11 '20 17:11 coultonluke

I'm afraid that any library that is going to manage 1,500 controlled inputs is going to run into performance issues, especially if you are going from 0 to 1,500 fields and then back again to 0 as in the sandbox. That's just a massive amount of listeners to register. I don't currently have the time to try to optimize for this extreme edge case. I'd recommend using uncontrolled inputs (you give up realtime validation and many other things that FF provides) for a use case with so many fields.

erikras avatar Feb 19 '21 15:02 erikras

Hi, @erikras, I believe the performance is related to second registration it's doing on the component initialization. I do have the PR for addressing the issue: https://github.com/final-form/react-final-form/pull/727

I can update that PR to latest, if you want me to, or not, if you think it's not worth it.

ryank109 avatar Feb 19 '21 16:02 ryank109

We are getting hit by the same problem with time to register initial fields scaling non-linearly for each added field. So a form with 500 fields may load in a couple seconds, but 2000 fields starts to take a few minutes on a very beefy machine. Makes our data-entry team very sad indeed.

We love the convenience of FinalForm, it would be a shame if we had to re-write this using uncontrolled fields etc.

slobo avatar Mar 01 '22 05:03 slobo

Just to add to this with our experience. We have "forms" of tabular data. Using some basic performance optimizations like virtualization helped a bit, but it has its tradeoffs. Currently, our main solution is to wrap each field in a flag which records whether its touched or not. When it is, we render a final form input, and uncontrolled if not. Again it has its tradeoffs and definitely adds more complexity.

Following @ryank109's PR in #727, I'd too would be interested in understanding

the reason behind why notifications on register matters. Originally posted by @ryank109 in https://github.com/final-form/react-final-form/issues/727#issuecomment-609094459

twgraham avatar Mar 14 '22 00:03 twgraham

@twgraham Could you please show in a sandbox how to archive the "wrap each field in a flag which records whether its touched or not. When it is, we render a final form input, and uncontrolled if not." Will be much appreciated. Don't want to rewrite the whole project to new lib

immakdas avatar Dec 29 '22 15:12 immakdas