Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wrap React component with little performance penalty?

My team uses React MaterialUI library. To provide consistent UI Pattern and make it easy for us to customise MaterialUI's component, we wrap each MaterialUI's component in our own component. For example:

const style = {} // our project custom style for ListItemText
const OurListItemText = ({primary, secondary, classes}: Props) => (
  <MuiListItemText
    primary={primary}
    secondary={secondary}
    className={classes.text}
  />
) // we only expose primary and secondary props of the original MuiListItemText.
// Team members are blocked from customising other MUIListItemText's props

export default withStyles(styles)(OurListItemText)

MuiListItemText is the original MaterialUI's component, while OurListItemText is our wrapper component. In our project, only OurListItemText is allowed to be used.

As the snippet above, OurListItemText does nothing but forward the props to MuiListItemText. However, this affects the performance quite a lot:

React Flame graph

ListItemText bar on the top is from OurListItemText while the one below is from MuiListItemText. If we use MuiListItemText directly, it could be ~50% faster (we have tried), which is noticeable when we have 100 ListItemText. Removing withStyles HOC improves a bit, but not significantly.

ListItemText is only one example, we have similar performance issue on other wrapped components. (2 Typography in the graph above is another pair of our-wrapper-component and MUI's-original-component)

How to improve the performance of those simple props-forwarding-components?

like image 826
Pahlevi Fikri Auliya Avatar asked May 05 '18 10:05

Pahlevi Fikri Auliya


People also ask

How do you wrap a component in React?

To wrap one component into another with React, we add the children prop into the parent component. We create the Wrapper component that accepts the children prop. And we put children in a div. Next, we create the Child component that takes the name prop and renders some text.

How do I stop Rerendering in React?

1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.

What is the smallest building block of Reactjs?

Elements are the smallest building blocks of React apps. An element describes what you want to see on the screen: const element = <h1>Hello, world</h1>; Unlike browser DOM elements, React elements are plain objects, and are cheap to create.

Which of the one is used to increase the React performance?

List virtualization, or windowing, is a technique to improve performance when rendering a long list of data. This technique only renders a small subset of rows at any given time and can dramatically reduce the time it takes to re-render the components, as well as the number of DOM nodes created.


1 Answers

wrapping a React component adds one extra level of full React lifecycle (i.e. the wrapper needs to be mounted). Is it possible to avoid this?

You can avoid the lifecycles by avoiding JSX and calling the functions directly instead.
Eg.

{Component({ data: 1, children: 'Hello' })}

instead of

<Component data={1}>Hello</Component>

This blog post claimed to achieve 45% speed improvement with their test case.

This syntax might not be as readable/understandable though.

Some quote from Dan Abramov regarding this issue:

We're looking at optimizations like this in the context of Prepack but there's nothing that's going to be immediately useable in the next couple of months. Within a year or two we might have something.

Note that unless you're creating thousands of elements, the performance difference won't be noticeable. Also unless your components are very flat and simple, the "pure win" from this optimization will likely be much less relevant in practice.

I wouldn't wait for Prepack to do the optimisation though since the timeline is uncertain and the resulting optimisation might not be identical to this.

As for the significance of the performance improvement, it'd depend on your project and the only way to be certain is to try out and see the improvement for yourself.

like image 134
Roy Wang Avatar answered Nov 15 '22 14:11

Roy Wang