My project needs to render dynamic forms, which could be really big (according to the data in the database). I build them using Formik because it needs complex validation, data mapping, state control. When it’s a big form, the form will be very sluggish when user inputting data in the form. Thus I have to find a way to improve its performance to gurantee that users can interact with the form smoothly.
Reason
The sluggish is due to re-render issue in Formik. Whenever you setFieldValue
or setValues
, Formik object will re-render. And it’s per keystroke. It means if you have hundreds of input field, every keystroke in any field will rerender the formik object. Since my form is dynamically updated according to any change user made in the form, and the page will re-calculate, re-validate immediately, the sluggish is appearent and affect the user experience.
Implementation
The improvement I made follows what Improving Formik Performance when it’s Slow (Material UI) suggests. The principle is to re-render formik based on onBlur event instead of per keystroke. The source code is here
The changes I made mainly in onBlur
. The code is here
const onBlur = (evt: React.FocusEvent<HTMLInputElement>) => {
const val = evt.target.value || "";
window.setTimeout(() => {
// Add your own logic
field.onChange({
target: {
name: props.name,
value: props.type === "number" ? parseInt(val, 10) : val,
},
});
}, 0);
};
After add the improved textField and usePropagateRef hook, the sluggish issue is gone.
Reference
Improving Formik Performance when it’s Slow (Material UI) Code source