根据MUI自己的doco和this answer-使用sx
的组件渲染速度明显慢于使用其他样式机制的组件。
从表面上看,sx
看起来只是一个替代的方便API,用于做同样的事情--所以我不希望它有如此不同的性能配置文件。
我的问题是:* 为什么 * 使用sx
渲染组件会慢得多-它有什么不同?这是一个完全不同的造型引擎还是什么?
我很好奇优化它的可能性,或者想出一个折衷方案,保留大部分的可用性,但省略任何导致速度减慢的功能。
请注意,这个问题是关于“为什么性能如此不同”-而不是“为什么你认为差异不重要”。
1条答案
按热度按时间20jt8wwn1#
当我开始深入研究时,我意识到我需要测量不同场景的性能,以便对我对
sx
prop的性能方面的理解有信心。MUI文档中的性能信息是使用基准测试收集的,可以在这里找到:https://github.com/mui/material-ui/tree/v5.13.2/benchmark/browser。
我相信这些基准测试的早期版本是基于这个存储库的一些变体:react-native-web repo被用作起点,因为它的“基准”包包含一个有用的框架,用于测量不同React元素渲染/样式化方法的性能。
我在这里创建了自己的版本:https://github.com/ryancogswell/mui-style-benchmarks。您可以将此作为进一步深入研究的起点。下面是我的测量结果和结论。
我的“Mount deep tree”Benchmark结果
该测试呈现了639个元素,每个元素具有大约17个CSS属性,除了减少CSS属性数量以显示性能影响的情况(“..._minimal”,“..._medium”)。
| 样式化实现|时间(ms)|实施说明|
| - -----|- -----|- -----|
| 内联样式|二十二点七八|没有样式引擎,只使用
style
prop|| mui_sx_full|三十六点八九|MUI Box
sx
prop with 17 CSS properties|| 多sx介质|二十四点零九分|带有9个CSS属性的MUI Box
sx
prop || 多sx极小|十八点十五分|带有4个CSS属性的MUI Box
sx
prop || 多样式盒|二十二点三八|MUI
styled
带有17个CSS属性的MUIBox
|| mui_styled_box_minimal|十七块九|MUI
styled
带有4个CSS属性的MUIBox
|| tss_react_makestyles|十七点十分|
makeStyles
来自tss-react
,带有17个CSS属性|| 多样式|十六点九三|带有17个CSS属性的MUI
styled
div
|| 多样式极小|十三点七七|带有4个CSS属性的MUI
styled
div
|| 情感风格|十六点六九|Emotion
styled
div
带有17个CSS属性|| 情感风格简约|12.76| Emotion
styled
div
带有4个CSS属性|| 情感_css|十二点五十八|Emotion
css
div
带有17个CSS属性|结论
styled
(例如import {styled} from '@mui/material/styles'
)只会给Emotion的styled
增加少量开销。styled
类似。styled
、Emotioncss
、MUIstyled
和MUIsx
prop在传递给样式引擎的CSS属性越多时开销越大。sx
prop的性能比styled
API下降得更快,因为传递给它的CSS属性更多。使用17个CSS属性,性能比styled
API(2x)差得多。sx
prop在小范围内表现良好(例如:< 5)的CSS属性。特别是,如果您已经在给定的情况下使用MUI组件,那么使用styled
Package 它或使用sx
prop(如果您只是使用少量CSS属性)之间没有任何有意义的性能差异。sx
prop 变慢的原因是什么?这是一个完全不同的造型引擎还是什么?
它不是一个不同的样式引擎。为
sx
prop所做的工作的输出被馈送到主样式引擎的styled
API中(例如:情感或风格化-成分);因此,将sx
prop与Box
组件一起使用肯定会比在div
上使用styled
的等效样式慢,因为sx
prop最终仍使用styled
,但会先执行额外的工作。sx
prop额外做了什么工作?styled
API调用styleFunctionSx,以便将sx
prop中的CSS属性转换为样式引擎所期望的形式。styleFunctionSx
遍历sx
属性中的所有CSS属性实际效果是,对于每个CSS属性,都有许多查找和函数调用,以查看是否需要转换CSS属性,即使在值传递而没有更改的情况下。
我很好奇优化它的可能性,或者想出一个折衷方案,保留大部分的可用性,但省略任何导致速度减慢的功能。
我确信
sx
prop 的性能改进是可能的,但我不认为有任何一个银可以轻松地使它更快。相反,它可能需要大量的小变化,每一个变化都几乎无法衡量,但累积起来会带来相当大的改善。挑战是在不同时使代码更复杂和/或更难维护和/或更容易出错的情况下进行这些更改。“保留大部分可用性”的主要妥协是直接使用Emotion的css prop。它可以以与
sx
prop类似的方式直接在元素上使用--只是失去了sx
prop提供的速记符号和主题查找。主题查找(例如对于颜色或间距单位)很容易通过使用组件中的useTheme hook直接从主题中获得。可以使用theme. API代替断点简写;尽管从DX的Angular 来看,sx
断点特性要好得多。我个人的方法是对大多数样式使用
tss-react
(这允许从基于JSS的makeStyles/useStyles
直接迁移,同时从v4迁移到v5),然后对某些只在给定页面上出现少量次数的组件使用sx
。