4
votes

I'm a developer of a fairly large react application. A part of the application is a detail form that is loaded dynamically and can consist of about 100 input fields of different data types (different components). The initial render of this form takes about 500ms on my laptop and i'd like to make it faster. I'm not quite sure what causes this render time but i share with you what i have:

enter image description here

This is a screenshot of the react profiler. As you can see there are some commits happening but one (orange) stands out. This is where the actual form is rendered. The form is a hierarchy of composed layouting boxes, other containers and the field container with the label and the data-type component inside. A single component does not take too long to render, but added up is why I end up with 500ms.

if we take a closer look at a small part of this screenshot above we can see this:

enter image description here

This is a small section inside a date edit field that gets rendered because we have a field of data type date. The first element is a styled component

const StyledDateAbstractWrapper = styled.div`
  && {

    align-items: center;
    cursor: ${props => props.immutable ? 'not-allowed' : 'default'};
    display: flex;

    input {
      display: ${props => props.immutable ? 'none' : 'block'}

      &:last-of-type {
        display: ${props => props.immutable ? 'block' : 'none'}
      }
    }
  }
`

as you see, nothing fancy. But it takes 2.3ms to render. And inside a styled button that takes 5 ms. Let's say i have a couple of these and that's how i end up with 500ms.

At this point i really think styled-components is the problem because i have some components take a couple of milliseconds as expected and many many small styled-component wrappers that each take more than a millisecond.

So my question... is there something i can further investigate? Or are there clear no-goes for styled components that are rendered many times such as element selectors?

Im using styled-components 5.0.1

Another approach would be using something like https://github.com/bvaughn/react-window but i dont have a list really. more some composed components.

Providing a running application is a bit tricky at the moment.

thank you for any suggestions

2

2 Answers

1
votes

I can't say much without seeing the proper implementation on this case, but from what I can think of you have a few options.

1 - Instead of having components with display: none you can simply remove them from the DOM with { !immutable && <Component /> }, this way the component won't take space in the VirtualDOM

2 - Second problem could be the Form library you are using, here is a performance overview of some of them. Performance Comparison. Maybe changing the lib you are using also helps.

-3
votes

First and foremost: usability wise, 100 form elements is insane! No user would ever go through the hell of filling this many (or even a quarter) of these elements. I suggest going back to your designer/product people and telling them to come up with a better way to model the business flow.

Really, forget about performance. No user will ever fill this form and it is better to realize and fix it now than in hindsight.

As for performance: 100 form elements is a lot! A desktop browser can surely handle that HTML, but rendering it all in React has its overhead in JS/DOM land. I'd say that half a second is quite good, considering the amount of work the browser has to carry out. And with styled-components in the mix, you're also straining the CSSOM.

There are additional optimizations and techniques which can be applied, though they won't be necessary once you restructure the app to not render so many DOM elements which your users won't be able to handle anyway.