Describe the bug
Mounting many (~1,000) <form.Field> components is quite expensive, and the cost appears to be worse than O(N)—something like O(N^2), I think (see graph below). In my production app, rendering about ~1,300 fields takes 10+ seconds and sometimes crashes the tab in Chrome. Removing <form.Field> but preserving the children with static values makes rendering effectively instant. My minimal reproduction (linked below) is not quite so egregious but still demonstrates the problem.
It's pretty easy to get to 1,000 fields, such as in a table with a 200 rows and 5 fields per row. Yes, I could virtualize the table or resort to many other tricks! But 200 rows is really not that many.
Your minimal, reproducible example
https://stackblitz.com/edit/vitejs-vite-bbfkr8kq?file=src%2FApp.tsx,src%2FApp.css,src%2Findex.css&terminal=dev
Steps to reproduce
You can play with the UI in the repro to change the number of fields rendered. Please feel free to critique or improve my methodology.
The repro tries to be careful to unmount the previous fields and only once done start a clock for the cost of a fresh mount. The "mount time" counts until the main thread is unblocked and the UI is responsive again. You can verify this by changing the count select to 2000 and trying to click to re-open the select. On my MacBook, it takes about 10 seconds before you can do so (compared with ~200ms on the plain input side).
I very crudely plotted the mount time for one trial at each of 100, 200, ... 900 fields. It's clearly worse than linear.
Expected behavior
I would hope for the cost of using <form.Field> to scale linearly with the number of fields. I would also hope for the cost to be low!
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
- OS: macOS
- Browser: Chrome
- Version: 148.0.7778.97
TanStack Form adapter
react-form
TanStack Form version
1.29.1
TypeScript version
No response
Additional context
I saw some issues related to this:
They suggest that a recent version of the library would have improved things. I have upgraded to the latest version (1.29.1) but the problem persists.
Also—thank you for the library! 😄
Describe the bug
Mounting many (~1,000)
<form.Field>components is quite expensive, and the cost appears to be worse than O(N)—something like O(N^2), I think (see graph below). In my production app, rendering about ~1,300 fields takes 10+ seconds and sometimes crashes the tab in Chrome. Removing<form.Field>but preserving the children with static values makes rendering effectively instant. My minimal reproduction (linked below) is not quite so egregious but still demonstrates the problem.It's pretty easy to get to 1,000 fields, such as in a table with a 200 rows and 5 fields per row. Yes, I could virtualize the table or resort to many other tricks! But 200 rows is really not that many.
Your minimal, reproducible example
https://stackblitz.com/edit/vitejs-vite-bbfkr8kq?file=src%2FApp.tsx,src%2FApp.css,src%2Findex.css&terminal=dev
Steps to reproduce
You can play with the UI in the repro to change the number of fields rendered. Please feel free to critique or improve my methodology.
The repro tries to be careful to unmount the previous fields and only once done start a clock for the cost of a fresh mount. The "mount time" counts until the main thread is unblocked and the UI is responsive again. You can verify this by changing the count select to
2000and trying to click to re-open the select. On my MacBook, it takes about 10 seconds before you can do so (compared with ~200ms on the plain input side).I very crudely plotted the mount time for one trial at each of 100, 200, ... 900 fields. It's clearly worse than linear.
Expected behavior
I would hope for the cost of using
<form.Field>to scale linearly with the number of fields. I would also hope for the cost to be low!How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
TanStack Form adapter
react-form
TanStack Form version
1.29.1
TypeScript version
No response
Additional context
I saw some issues related to this:
They suggest that a recent version of the library would have improved things. I have upgraded to the latest version (
1.29.1) but the problem persists.Also—thank you for the library! 😄