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

Pah*_*iya 15 performance reactjs 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)
Run Code Online (Sandbox Code Playgroud)

MuiListItemText是原始的MaterialUI的组件,OurListItemText而是我们的包装器组件.在我们的项目中, OurListItemText允许使用.

作为上面的片段,OurListItemText除了将道具转发之外什么都不做MuiListItemText.但是,这会对性能产生很大影响:

反应火焰图

ListItemText顶部的酒吧来自OurListItemText下方的酒吧MuiListItemText.如果我们MuiListItemText直接使用,它可以快〜50%(我们已经尝试过),当我们有100时,这是显而易见的ListItemText.删除withStylesHOC略有改善,但并不显着.

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

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

riw*_*iwu 6

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

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

{Component({ data: 1, children: 'Hello' })}
Run Code Online (Sandbox Code Playgroud)

代替

<Component data={1}>Hello</Component>
Run Code Online (Sandbox Code Playgroud)

这篇博文称其测试用例的速度提升了45%.

但是,此语法可能不是可读/可理解的.

Dan Abramov就此问题引用了一些话:

我们在Prepack的背景下看到这样的优化,但是在接下来的几个月里没有任何东西可以立即使用.在一两年内,我们可能会有所收获.

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

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

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

  • 博客文章是为旧版本的React编写的.我几天前看过它并且给人留下了深刻的印象,但是对于较新的版本没有找到任何类似的比较. (2认同)