如何在没有性能损失的情况下包装React组件?

时间:2018-05-05 10:06:59

标签: reactjs performance material-ui

我的团队使用React MaterialUI库。为了提供一致的UI模式并使我们能够轻松定制MaterialUI的组件,我们将每个MaterialUI的组件包装在我们自己的组件中。例如:

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是原始MaterialUI的组件,而OurListItemText是我们的包装器组件。在我们的项目中,仅允许使用 OurListItemText

如上面的代码段所示,OurListItemText除了将道具转发给MuiListItemText之外什么都不做。但是,这会对性能产生很大影响:

React Flame graph

顶部的

ListItemText栏来自OurListItemText,而下面的栏位于MuiListItemText。如果我们直接使用MuiListItemText,它可能会快50%(我们已经尝试过),当我们有100 ListItemText时,这是显而易见的。删除withStyles HOC略有改善,但并不显着。

ListItemText只是一个例子,我们在其他包装组件上有类似的性能问题。 (上图中的2 Typography是另一对our-wrapper-component和MUI的原始组件)

如何提高那些简单的道具转发组件的性能?

1 个答案:

答案 0 :(得分:6)

  

包装React组件会增加一个额外级别的完整React生命周期(即需要安装包装器)。有可能避免这种情况吗?

您可以通过避免JSX并直接调用函数来避免生命周期 例如。

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

而不是

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

This blog post声称他们的测试用例可以提高45%的速度。

但是这种语法可能不是那么可读/可理解。

引用Dan Abramov regarding this issue

  

我们在Prepack的背景下考虑这样的优化,但在接下来的几个月里没有什么可以立即使用的。在一两年内,我们可能会有一些东西。

     

请注意,除非您创建数千个元素,否则性能差异不会明显。除非您的组件非常扁平和简单,否则&#34;纯粹的胜利&#34;从这种优化中可能在实践中不那么重要。

我不会等待Prepack进行优化,因为时间轴不确定,结果优化可能与此不同。

至于性能改进的重要性,它取决于您的项目,唯一可靠的方法是尝试并亲眼看到改进。