【问题标题】:Is there a performance difference between the sx prop and the makeStyles function in Material UI?Material UI 中的 sx 道具和 makeStyles 函数之间是否存在性能差异?
【发布时间】:2021-07-14 17:58:03
【问题描述】:

我刚开始使用 Material UI,我知道它在 JS 中使用 CSS 样式化组件。
我在如何创建样式的文档中看到了 2 种方法:

使用sx 属性:

<Box sx={{ backgroundColor: 'green' }}/>

使用makeStyles 方法:

makeStyles({
  root: {
    backgroundColor: 'green'
  }
})

我知道 JS 中的 CSS 性能远低于原生 CSS。
但是在我刚刚编写的这两种方法中,哪一种性能更高(如果有的话)?

顺便说一句,我使用的是 Material UI 版本 5,它声称在情感方面的整体性能比 JSS 更好

【问题讨论】:

    标签: javascript css reactjs material-ui


    【解决方案1】:

    对于静态样式(即基于道具的非动态样式),JSS 比 Emotion 稍快。对于动态样式,JSS 比 Emotion 慢得多——Emotion 对于静态和动态样式的性能相似。

    您可以在以下问题中找到有关 JSS 和 Emotion 之间静态样式的性能差异的信息:

    对于静态样式,JSS 比 Emotion 快大约 10%。对于动态样式,JSS was 6 times slower than Emotion 在 Material-UI 团队执行的一项测试中,这就是为什么 JSS 从 v5 可能的样式引擎列表中被淘汰的原因。

    https://next.material-ui.com/system/basics/#the-sx-prop 的文档包含以下性能信息:

    Benchmark case Code snippet Time normalized
    a. Render 1,000 primitives &lt;div className="…"&gt; 100ms
    b. Render 1,000 components &lt;Div&gt; 120ms
    c. Render 1,000 styled components &lt;StyledDiv&gt; 160ms
    d. Render 1,000 Box &lt;Box sx={…}&gt; 370ms

    我希望直接使用 Emotion(使用 styled approachcss prop)的性能类似于 Benchmark 案例 c。我希望 makeStyles 的静态样式会比这稍快(在 140 毫秒到 150 毫秒范围内),但不会快很多。您可以看到 sx 属性明显变慢,但请记住,额外的 200 毫秒开销是针对 1,000 个元素的,因此额外的开销仍然仅为每个渲染组件的五分之一毫秒。 sx 属性增加的开销取决于你传递给它的 CSS 属性的数量。对于少数 (styled 和 sx 之间的差异并不如上表所示那么显着。

    我不记得曾看到 Material-UI 声称 v5 总体上比 v4 快。 v5 确实添加了许多新功能,如果使用 JSS 实现这些功能会非常缓慢(由于利用动态样式),因此他们能够在添加这些功能的同时保持与 v4 相当的样式性能。

    makeStyles 与 Material-UI v5 一起使用的最大缺点是,您会导致用户同时下载 JSS 和 Emotion 作为捆绑包的一部分。如果您有一个使用 v4 构建的现有应用程序,并且已经大量使用 makeStyles(您现在正在迁移到 v5),那么一个迁移选项是 tss-react,它保留了与 makeStyles 类似的语法,但由 Emotion 支持JSS 并具有与styled API 相似的性能。现在有一个 codemod 用于将 JSS 样式迁移到 tss-react

    相关回答:Why is the `sx` prop so much slower?

    【讨论】:

    • 你能在material ui v5中使用makeStyles吗?不只是sx prop吗?
    • @TwoHorses 是的,在 v5 中,您可以通过 @material-ui/styles 包 (next.material-ui.com/guides/migration-v4/…) 使用它,但它被视为已弃用。 sx 属性只是为 Material-UI 组件样式添加的便利实用程序,但您仍然可以通过任何其他样式解决方案提供 CSS 类。
    • 因此,如果 sx 仅被 Box 组件接受,并且我希望尽可能接近首选 MUI 方式来设置我的组件样式,删除所有使用 makeStyleswithStyles 赞成还是 Emotion 或 styled-components 将是要走的路?哎呀,在我的情况下,这将是很多工作。感谢您抽出宝贵时间在这里为您提供见解。
    • @hotpink sx 被所有 MUI 组件支持——不仅仅是 Box。
    • @RyanCogswell 您是否建议将makeStyles 替换为styled,并由于性能影响而谨慎使用sx?有一些用户被sx perf 数字吓倒了,尽管它对动态样式来说是一个很好的改进。与sx 属性相比,我还对动态styled(传递回调而不是样式对象)的性能感兴趣。
    【解决方案2】:

    我遇到了同样的问题,但后来我决定根据@emotion/css整体重建makeStyles:

    https://dev.to/atonchev/material-ui-5-the-easiest-way-to-migrate-from-makestyles-to-emotion-1i9l

    基本上,您需要制作一个自定义挂钩useClasses,它将您的theme =&gt; ({... 函数或样式对象重新加工成类,其使用方式与makeStyles 完全相同。

    与在 mui codemod 中提出的方式相比,使用这种方法还有一个 IMO 巨大的好处

    https://github.com/mui-org/material-ui/blob/v5.0.0-beta.2/packages/material-ui-codemod/README.md#jss-to-styled

    因为emotion/css会缓存一个className相同的样式,而且你基本上会复用类,例如:

    const styles1 ={
      someClass1: { color: 'black' }
    }
    
    const styles2 ={
      someClass2: { color: 'black' }
    }
    

    styles1.someClass1styles2.someClass2 在生产中将具有相同的类名,例如css-1qs4g5r。我已经试过了。但是在 mui 提出的 codemode-way 中,您将拥有唯一的类名,它们并不是真正可重用的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 2012-03-05
      • 2014-02-23
      • 2010-10-02
      • 1970-01-01
      相关资源
      最近更新 更多