Material-ui: [RFC] v5样式解决方案💅

创建于 2020-08-24  ·  105评论  ·  资料来源: mui-org/material-ui

该RFC是在v5中更改Material-UI样式解决方案的建议。

TL:DR;

有什么问题?

  • 维护和开发出色的样式引擎需要花费大量时间。 我们已经亲身体验了。 在过去的12个月中,我们倾向于将时间花在我们的核心价值主张上:UI组件,而不是改进样式引擎。 处理它具有很高的机会成本。
  • 我们一直在支持组件的动态样式方面遇到问题。 我们自定义的动态风格的执行情况(基于道具)的表现也不是很大(见下面的性能基准)。 这严重限制了我们可以提供的开发人员体验的质量。 它是围绕自定义性或易于编写样式来改进我们的API的障碍物。 例如,它将解锁:样式utils propscolor变量custom变量
  • 总体而言,React社区尚未投票赞成大规模使用JSS(JSS很好并且仍在使用)。 3年前,我们押注了最佳选择。 我们必须认识到现在有更好的选择。 通过建立在更流行的现有样式解决方案之上,我们可以更快地移动并更好地解锁DX / UX。
  • 许多开发人员使用样式化组件来覆盖Material-UI的样式。 最终用户在捆绑包中找到了两个CSS-in-JS库。 不是很好。 如果我们可以为不同的CSS-in-JS库提供不同的适配器,那就更好了。 (潜在的问题:我们可能需要重新编写核心样式以匹配所用引擎的语法🤷‍♀️)

有什么要求?

无论我们选择使用哪种样式引擎,都必须考虑以下因素:

  • 性能:速度越快越好,但是我们愿意牺牲一些性能来改善DX。
  • 捆绑包大小:低于我们当前的14.3 kB(已压缩)会很棒。
  • 支持并发模式: @material-ui/styles在我写作时有部分支持。
  • 支持SSR
  • 简单的定制
  • 允许动态样式
  • 良好的社区规模
  • 主题化
  • 单位特异性
  • RTL
  • 打字稿

如果可以支持以下内容,那就太好了:

我们有什么选择?

  • 样式组件
  • 情感
  • JSS(当前包含在material-ui中)
  • Styletron
  • 阿芙罗狄蒂
  • 费拉
  • 其他?

比较方式

性能

以下是一些流行库的动态样式的基准测试(请注意,Material-UI v4仅使用性能良好的静态样式):

公关参考: https :

基于性能,我认为我们应该消除:JSS(当前以@ material-ui / styles包装),styletron和fela。 那会给我们留下:

  • 样式组件
  • 情感
  • 阿芙罗狄蒂
  • JSS
  • 反应式加速器
  • 费拉

动态道具

基于开放的问题,阿芙罗狄蒂似乎不支持动态道具: https :
我认为这意味着我们也应该从我们的选择中删除该选项,让我们拥有:

  • 样式组件
  • 情感
  • 阿芙罗狄蒂
  • 反应式加速器

npm

虽然styled-componentsemotion都非常受欢迎,但是当时react-styletron的时间或写作远远落后于每周约12500次下载(我认为这是一个很强的理由为什么我们应该消除它,就好像我们决定使用它一样,社区将再次需要在其应用程序中使用两个不同的样式引擎。

以下是撰写本文时按周下载量排列的列表:



请注意,故事书对情感有依赖性。

  • 样式组件
  • 情感
  • 反应式加速器

支持并发模式

  • 情感:是的。 从v10开始,根据其发布公告,它是严格模式兼容。 我已经在一个可以正常工作的简单项目上对其进行了测试。
  • 样式化的组件: Partial 。 在严格模式下,全局样式至少存在一个错误

固态继电器

星星

  • 样式组件:30.6k
  • 情感:11.4k
  • JSS :5.9k

在文档上进行流量

SameWeb估计的每月会话数:

  • sass-lang.com:〜476K /月(用于比较)
  • styled-components.com:每月〜239K
  • 情感.sh:〜59K /月
  • cssinjs.org :每月少于30k(用于比较)

用户反馈

根据调查,有53.8%的用户使用Material-UI样式(JSS),这并不奇怪,因为它的引擎来自Material-UI。 但是,我们可以看到20.4%的人已经在使用样式组件,考虑到我们没有直接的支持,这是一个很大的数字。 根据调查,目前约有1.9%的开发人员使用了Emotion。

有了这些数字,我们希望为样式化组件提供更好的支持,因此我们应该考虑这一点。

浏览器支持

  • 情感:现代的常绿浏览器+ IE11
  • 样式化的组件:v5没有记录,但是以前的版本支持以下内容

捆束尺寸

最好的选择是什么?

默认引擎

即使我们决定支持多种引擎,默认情况下,我们仍然需要倡导一种引擎,并在演示中记录其中的一种。

样式组件

优点:

  • 拥有最大的社区,人们喜欢使用它。
  • 从v5开始的性能不错。

缺点:

  • 这意味着所有组件样式都需要使用styled API创建,这意味着对于开发人员而言,如果需要重新样式化,他们将始终具有包装器组件。
  • 缺乏完整的并发支持,这可能会在将来造成阻塞。

情感

优点:

  • 社区相对较大,正在发展。
  • 很棒的表演。
  • 并发模式+ SSR可能是开箱即用的。
  • CSS道具可用于覆盖。
  • 源地图支持。
  • 小一点。

缺点:

支持多个

通过为它们提供内部适配器,我们可能会尝试支持多种CSS-in-JS解决方案。 我们需要考虑的一些事情是,我们可能需要对样式进行重复的工作,因为它们之间的语法是不同的(与样式化组件/情感相比,至少是jss)。 无论将采用哪种解决方案,我们都将重用主题对象。

较少涉及的支持可能来自styled ,因为人们可能会做一些webpack配置来决定使用哪个-(这只是要考虑的事情)。

附加评论

可以作为自定义样式目标的组件上的确定性类名

关于类的外观以及开发人员如何针对它们,我想比较一下我们现有的类以及如何使用新方法解决问题。

作为示例,我将使用Slider组件。 当前是生成的DOM的样子:

每个类都有很好的描述性语义,人们可以使用这些类来覆盖组件的样式。

另一方面,情感,样式组件或任何其他类似的库将创建一些哈希作为类名。 为了解决此问题并为开发人员提供用于定位类的相同功能,每个组件都将添加开发人员可以基于道具定位的类。

这意味着,除了情感所产生的类之外,每个组件仍将具有我们以前拥有的类,例如MuiSlider-rootMuiSlider-colorPrimary ,唯一的区别是该类现在将是纯粹用作选择器,而不是定义组件的样式。 这可以像钩子一样实现-useSliderClasses

结论

无论我们选择哪种解决方案,我们都将使用styled API,这两个接口都支持该API。 这将使我们能够轻松地支持样式+未样式化的组件(可能带有webpack别名,例如使用preact)。

在研究了最后的两个选择之后,核心团队建议我们保持情感。 一些关键要素:

样式元素和情感之间的少量迁移成本

已经使用样式化组件的开发人员应该几乎可以毫不费力地使用情感。

除了包装器组件之外,还有其他方法可以添加替代项

如果开发人员不想创建包装器组件,则可以通过情感来支持cx + css,这对于开发人员将其用作添加样式替代的替代方法可能是有益的。

肯定支持并发模式:+1:

感谢@ryancogswell对这个主题进行了更深入的研究。 到目前为止,我们没有在@emotion的代码中找到任何让我们担心并发模式无效的东西。
我们还研究了来自样式组件的createGlobalStyle ,以与情绪的Global组件进行比较。 它在渲染过程中完成了大部分工作(对于严格/并行模式本来就存在问题),并且仅使用useEffect清除其清理功能中的样式。 createGlobalStyle需要完整的重写才能在并发模式下使用-如果从不提交渲染,则在渲染期间添加样式是不可行的。 好像有人在上个月尝试过对其进行一些进一步的更改来重写它,所以我们将需要跟踪这一进展。

特异性如何处理

Emotion的文档建议将CSS组合成一个类,而不要尝试利用多个类名中的样式。 在v5中,将应用我们现有的全局类名称,而不会附加任何样式。 情感样式的组件的组合会自动将样式合并为一个类。 至少在Material-UI定义的样式内部,这有可能摆脱这些样式表顺序问题,因为每个组件的样式都由单个类名:+1:驱动。
因此,我们将具有全局类名(供开发人员以各种方式进行自定义定位),然后每个元素具有一个单独的(通过情感方式)生成的类名,以合并流入其中的所有CSS源。
然后根据构成的顺序通过情感来处理特异性。
所有使用情感的合成(无论是渲染时间还是定义时间合成)都会在元素上产生单个类。
样式化组件在渲染时合成方面不起作用(定义时合成确实合并为一个类)。 样式化组件中的相同组成导致将多个类应用于同一元素,并且特异性无法达到我的预期。

备择方案


你怎么看待这件事?

discussion

最有用的评论

作为情感的维护者说话-听起来很棒sound

我们还应该能够发布一个新的重要版本,不会有任何革命,只需进行一些清理,整体改进,深入了解钩子和TS类型改进(更好的推理和性能)即可。

哦,重写了解析器! 消除了Emotion和Styled-Components中的一些边缘错误(目前,它们都使用相同的解析器)。 它既小又快。

所有105条评论

仅作一些更正:

总体而言,React社区已投票反对大规模使用JSS。

相反,我建议React社区不要投票赞成JSS。 也许它不像其他解决方案那样“上市”?

我们没有赌正确的马。

我们打赌唯一的一匹马-那是一场单马比赛。 当时没有其他可用的解决方案在所有方框中打勾。

情感听起来很棒! 我喜欢获得TS支持,例如,自动完成功能以及使用CSS-in-JS进行打字的所有好处-在构建UI或样式组件时,这仍然可能吗?

最后一点让我明白了! 我很乐意通过在beta标志后进行操作或开发某些功能来提供帮助:

所有使用情感的合成(无论是渲染时间还是定义时间合成)都会在元素上产生单个类。
样式化组件在渲染时合成方面不起作用(定义时合成确实合并为一个类)。

我还指出,主题对象将保持不变,在我看来,这是对应用程序进行主题化的绝对最佳方法! 我无话可说:震惊:

感谢您在M-UI方面所做的出色工作。 我喜欢这个项目的发展方向。

走向更标准化的样式化方式是可行的方法。 我知道团队和社区将解决问题,而v5(听起来)会更加出色! :火箭:

作为既使用样式组件又使用情感的人,我可以确认在它们之间进行过渡既轻松又轻松。

+情感对打字稿更友好

作为情感的维护者说话-听起来很棒sound

我们还应该能够发布一个新的重要版本,不会有任何革命,只需进行一些清理,整体改进,深入了解钩子和TS类型改进(更好的推理和性能)即可。

哦,重写了解析器! 消除了Emotion和Styled-Components中的一些边缘错误(目前,它们都使用相同的解析器)。 它既小又快。

重大更改如何处理,哪个选项会引入更多重大更改(如果有)?

不确定是否会有所作为,但是基准是通过情感和/或样式组件的babel插件完成的吗? 它们有助于进一步优化事物。

据我了解,MUI之前曾表示将使用样式,所以这是一个惊喜。 我认为情感是一个很棒的图书馆,但是目前有更多人使用样式,重要的是,如果他们不想迁移到情感上,就必须找到给他们好的选择的方法

@ ee0pdt情感非常像风格。 我认为这是Emotion对样式组件的全部选择的一部分。 有明显的好处,移民债务几乎没有。

整个章节将通过为开发人员提供选择来支持两者。 那可能是一条路,但是再说一次,标准化可能会帮助我们更多。 完整的并发性和没有包装器组件对我来说是一个难题。 我知道其他人可能想要样式提供的东西,应该考虑一下。 我宁愿朝着标准化迈进

为什么排除styletron反应? 它遗漏了一个未考虑的整体指标,即内存消耗。 默认的styletron引擎(和fela)是atomic。 虽然速度较慢,但​​可以节省大量内存。 看到许多反应页面后无所事事,过一会儿就会超过1GB,这有点令人担忧。 之后浏览器将冻结。

使用原子框架,随着每个原子“类”的缓存,跨组件的性能随着时间的推移在全球范围内不断提高。 可能也没有反映在测试中。

只要支持SSR就满意

我只是从最初的样式化组件问题中撤回了投票:sweat_smile:-首先通过故事书了解了情感,但是It will mean that all components styles need to be created using the styled API, which means for developers they will always have wrapper components if they need to re-style.让我切换了。

感谢大家的快速反馈。 以下是一些评论/问题的答案。

重大更改如何处理,哪个选项会引入更多重大更改(如果有)?

@ sag1v使用styled-componentsemotion不会引入或多或少需要我们处理的重大更改。 总体上的重大更改将围绕主题内部的替代显示如下:

// previosly
root: {
  contained: {
    '&$disabled': { // <-- this part will need to be transformed
      color: 'red',
    },
  },
  containedPrimary: {
    color: 'blue',
  },
}

// after
root: {
  contained: {
     '&.Mui-disabled': {
      color: 'red',
    },
  },
}

但是,由于emotionstyled-components之间的样式语法相同,所以不会有任何区别。

不确定是否会有所作为,但是基准是通过情感和/或样式组件的babel插件完成的吗? 它们有助于进一步优化事物。

@ hc-codersatlas不,但是性能是介于前几名之间的,所以我不认为这会有所作为。 好电话难!

为什么排除styletron反应? 它遗漏了一个未考虑的整体指标,即内存消耗。 默认的styletron引擎(和fela)是atomic。 虽然速度较慢,但​​可以节省大量内存。 看到许多反应页面后无所事事,过一会儿就会超过1GB,这有点令人担忧。 之后浏览器将冻结。

使用原子框架,随着每个原子“类”的缓存,跨组件的性能随着时间的推移在全球范围内不断提高。 可能也没有反映在测试中。

我对为什么排除styletron-react对此可能会引起误解,将立即更新PR描述。 性能非常好,但是我对styletron的最大关注是社区: https: //www.npmtrends.com/styletron-react-vs-@emotion/core -vs-styled-components情感和样式化组件在过去6个月中,下载量超过2000000,styletron约为15000。

原子CSS也可能导致覆盖问题,因为每个类名仅包含一个样式器规则。

我有一个问题,如果我们决定使用情感,是否要在所有文件之上添加以下代码?
/ ** @jsx jsx * /
这是JSX编译指示,默认情况下,JSX编译指示是React.createElement

如果您在情感中使用css属性,则需要添加它。 对于styled API以及常规的className API,您不需要它。

可以跳过添加JSX pragma的操作,但是它需要额外的Babel设置,并且对工具的支持也较差-例如,TS无法像使用JSX pragma时那样准确地检查CSS属性。 可以在这里找到更多信息: https :

@mnajdova谢谢。 我只是希望内存使用量可以涵盖更多,而不是特别为Styletron提供担保。 至于下载或社区-“仅” Uber使用styletron :),所以不用担心。 首先为情感投票。

如果有babel插件或类似的插件可以将静态样式转换为真实的CSS类,那就太酷了。 已经有一个名为compiled的类似库。 实际上,大多数样式都是静态的。

为了使Fela有用,需要使用fela-plugin-rtlfela-plugin-prefixer类的插件,这会使性能更差(https://github.com/microsoft/fluentui/pull/12289)🐢然后您可能最终会得到Emotion(https://github.com/microsoft/fluentui/pull/13547),因为有时它的速度可能是Fela的两倍📦

我唯一关心的是必须使用Emotion的css thing。 根据我的经验,这是一个很大的危险信号。 我不得不从大型代码库中删除此类内容,这并不有趣。 为什么? 因为它是一种抽象,带来了比长期解决的问题更多的问题。

在大多数情况下,我们尝试使用styled函数,但是对于makeStyles函数在某些情况下生成某些类,我们感到很满意。

希望这两个API都没有重大变化,并且我也不必使用css宏。

我唯一关心的是必须使用Emotion中的CSS Thing。

@yordis您绝对不会被迫使用css道具。 我怀疑makeStyleswithStyles用法会有所变化。 希望所需的更改量可以主要限制在导入上的codemod上。 我认为makeStyleswithStyles使用的方法不支持使用情感,因此,我希望这些API的任何持续支持都将通过单独的软件包提供(因此,“ @ material-ui / core“不再具有JSS依赖项),在v5发布后,它大概只会得到最少的维护(关于makeStyleswithStyles发生的事情的详细信息尚未确定但是,这仅仅是我对情感前进的影响的推测。

👍选择使用情感。 避免使用styled styled-componentsstyled API是我的团队选择Emotion的原因之一(除css道具外,它还支持类似的styled API)。 我们目前使用Emotion进行Material UI样式自定义,并且效果很好。 内置的支持只会锦上添花。

关于这些事实:

许多开发人员使用样式化组件来覆盖Material-UI的样式。 最终用户在捆绑包中发现了两个CSS-in-JS库

支持并发模式
样式组件:部分

如果样式化组件完全支持并发模式,那么这是一个更明智的选择,因为大多数开发人员都在使用样式化组件(不包括JSS)覆盖MUI? 如果需要包括两个css-in-js解决方案,那么关于情感在捆绑大小上变小的问题就没有意义了。 而且我认为MUI的大多数实际应用都涉及覆盖其样式。

在我和我的团队使用Emotion作为样式化组件的主要方式的地方,我遇到了情感库中存在的一些低效率问题。 我想知道你们对下面解释的这些低效率有何看法。

考虑下面的Emotion StyledComponent;

const StyledComponent = styled.div`
  ${({color}) => color && `color: ${color}`};
  display: flex;
  justify-content: center;
  align-items: center;
  background: teal;
  font-size: 20px;
  padding-top: 8px;
  padding-bottom: 8px;
  margin-top: 12px;
  margin-bottom: 12px;
  border: 1px solid grey;
`

当颜色属性更改时,将复制所有css属性( display: flex, justify-content, ..., border: 1px soild grey )生成新的css类。 这将导致css类具有与每种颜色道具完全相同的css道具,请参见下文;
image

我们发现的另一个效率低下的情况是,当新组件从StyledComponent以上衍生时,它将创建一个新类,其中所有css道具都从基数StyledComponent复制而来。 考虑下面;

const DerivedComponent = styled(StyledComponent)`
  font-family: monospace;
`

它创建另一个css类,该类仅将font-family: monospace到上述从StyledComponent生成的css类中。 也就是说,它创建了一个css,具有从StyledComponent复制过来的所有道具,如下所示;

image

现在,如果将以上StyledComponentDerivedComponent一起使用,我们(最初)有两个具有重复css props的css类(仅在font-family中有所不同)。 如下所示;

image

可以想象,相互具有重复的css道具的多个css类可以快速增长。

我发现使用Emotion可以将组件样式组合在一起,最终得到具有许多重复CSS道具的CSS类。

我不确定每个css类中是否有重复的css道具会对应用程序产生明显影响,但是我想知道是否在选择使用情感时考虑了这一点。

我不怀疑Emotion在运行时创建和应用CSSStyle的性能。 情感是应用CSSstyle最快的一种,这在perf测试中很明显。
我只是担心CSSstyle膨胀。 由于Emotion可以是SSR(ed),这意味着样式以HTML内联,所以我们可能会不必要地HTML肿(带有css样式标签)HTML文件。 反过来,这会导致更多标签供浏览器使用不必要的CSS道具解析。

如果样式化组件完全支持并发模式,那么这是一个更明智的选择,因为大多数开发人员都在使用样式化组件(不包括JSS)覆盖MUI? 如果需要包括两个css-in-js解决方案,那么关于情感在捆绑大小上变小的问题就没有意义了。 而且我认为MUI的大多数实际应用都涉及覆盖其样式。

@petermikitsh我们得出情感结论的原因实际上是结论中的四点

  • 样式元素和情感之间的少量迁移成本
    已经使用样式化组件的开发人员应该几乎可以毫不费力地使用情感。
  • 除了包装器组件之外,还有其他方法可以添加替代项
    如果开发人员不想创建包装器组件,则可以通过情感来支持cx + css,这对于开发人员将其用作添加样式替代的替代方法可能是有益的。
  • 肯定支持并发模式👍
  • 如何处理特异性

牢记第一点,如果开发人员确实希望避免在捆绑包中使用两个css-in-js解决方案,那么迁移到情感上的迁移成本确实很小,而且它支持styled以外的其他API。

@ ko-toss感谢您撰写本文,这些都是不错的地方。 情感生成具有所有样式的一个className的事实,使其成为解决替代的更好引擎。 我们生成多个className可能存在的问题是,最后写入的类将获胜,这在将来可能会成为问题。

在另一个项目中,我使用的是原子CSS,从内存消耗方面来看要好得多,因为所有CSS规则都只编写一次,但是要进行可预测的覆盖非常困难,因为每个className都是一个原子规则,胜过一个,如果您不确定以前是否处理所有样式并正确合并它们,则取决于它们的编写顺序,这最终可能会影响性能。

另一方面,我相信使用任何css-in-js解决方案,人们将不仅会随机创建样式的无限组合,而且仍会根据props的值进行结构化的构建。

但是,这些都是我们要牢记的要点,非常感谢分享sharing

  • 其他?

关于[stylex]概念兼容性如何(例如[style9])

  • 其他?

style9或任何其他与stylex idea兼容的CSS引擎

这似乎需要构建时间设置,这会阻止许多人使用它,尤其是初学者。

(这是仅供参考,情感是一个不错的选择)

https://github.com/cristianbote/goober(1kB ,性能比情感还差)

我目前还没有经验,但是有一天我想尝试一下。
image
image

@cztomsik类似于https://github.com/kuldeepkeshwar/filbert-js,但不支持JavaScript语法(仅CSS模板字符串)

以下是使用Google灯塔在互动时间上进行的一些测试:

https://jantimon.github.io/css-framework-performance/

css-lighthouse-scores

仅供参考,我已经完成了样式组件v5,情感v10和情感v11(带有/不带有babel插件),香草API,css props API和样式API的一些详细基准测试。 希望这对讨论有所帮助!

https://github.com/simnalamburt/css-in-js-benchmark

您是否考虑过新一波的CSS-in-js库,这些库严重依赖原子CSS和Typescript支持?

您是否考虑过新一波的CSS-in-js库,这些库严重依赖原子CSS和Typescript支持?

它不是基准,但目前otion比情感慢2〜4倍。 我认为otion确实具有很大的潜力,并且相信还有优化的空间,但是otion尚未真正为生产做好准备。

我还没有测试针脚。 😃

实际的零运行时库又如何呢? 我还没有看到有人提到利纳里亚

我偶然发现了linaria,我真的很喜欢。 我唯一担心的是,动力学道具的样式仅取决于css变量,并且基于https://github.com/callstack/linaria/issues/445对IE 11不提供任何支持。而且与styled-componentsemotion的社区要小得多。

@TheHolyWaffle
Linaria很棒。
如果正确设置,我相信这是css-in-js(在开发经验方面)和纯css(无法超越纯css性能)中最好的。 它甚至优化(重复)并重用CSS规则。
但是利纳里亚需要建立和捆绑步骤,这对初学者来说很难。

我希望看到具有类似API表面的其他css-in-js库的端口,例如filbert-js / goober

@kuldeepkeshwar一旦我们调查了样式化API的适配器,我们将通知您:)

https://compiledcssinjs.com/如何适应所有这些? 这似乎是一种非常有趣的方法。 Compiled还为该项目运行RFC,事实证明,该RFC非常适合开源和协作。 _眨眼眨眼_

我认为对Web进行样式设计的未来非常非常光明,我希望Material-UI将成为对任何应用程序进行样式设计的必不可少的部分。

我对编译工作原理的解释是:

这种转换使我们能够将您的组件交付给任何消费者,而无需他们配置/设置他们的工具。 只需导入即可。 它功能强大,而且更重要的是,它与JS库中的当前CSS相同,仅需一抓即可。

_CSS不能在运行时生成。

这个单一的约束为我们打开了很多门。 建立时间优化。 运行时保证。 性能瓶颈消失了。

另一方面,我想指出,受欢迎程度对于一个好的项目并没有多大意义。 我爱MUI和到目前为止所做的工作; 我也认为它已成为高级产品真是太棒了。
但是,为了流行起见,选择一个“受欢迎的”名字并不是一个合理的论据。
我已经看过多次引用流行性,并且即使考虑到x人数是否使用x技术,我也非常不喜欢-MUI(在我的书中)专注于性能,DX和其他方面,而不仅仅是流行。

MUI并不总是拥有6万颗星,它之所以得到它们,是因为它选择了(或接近)最佳技术,而不是因为它选择了流行技术。

如果基于大众投票进行选择是为了成为一个更广泛可及的项目,那是业务问题,而不是可能的性能提升。 一个项目可以有或没有用户。 它死于错误的选择。 我认为围绕这​​句话有很多说法,并且读到“它不够流行,因此是一个不好的选择”,这响起了很多响声。

人们使用正确的产品是因为它是好产品,而不是因为它使用了流行的技术。 MUI曾经是利基市场,但是即使它有CSS-in-JS也很出名,但并没有赢得大众的欢迎。 它仅具有一些令人惊奇的属性,并且做出的选择不是基于当前社区,而是基于实际的DX和性能。

注意到这一旁注,我本人也代表了全民投票。 所以如果有的话,我也在破坏自己。 我从选择一种不太受欢迎的产品中没有任何个人收获,我认为谈论革命和变革时,根本不应该将人气视为“全部”。 请根据实际选项重新考虑其中的一些选项,而不是根据选项的当前流行程度重新考虑人们认为它们是什么。

最后,对于MUI的每一个想法和任何时间,我深表感谢。 在过去的几年中,我遵循所有标准制定了一些出色的(非常私有的)解决方案,这可能要花几个月甚至几年的时间才能做到! 我无法将我的赞赏描述得足以使它在纸上散发出来。🙇‍♂️🙏♂‍♂️

我很好奇“是否编译”是一个选项,以及它如何与适配器等配合使用。 我认为编译方法:

通过静态分析代码,然后将其转换为Compiled Components,Compiled会在构建时使用JS编译CSS。 我们需要使用该组件的所有内容都包含在JavaScript包中。

考虑到整个编译的“运行时css”约束,这是一个可以考虑的路径。

我是作为Emotion维护人员说的-编译的很棒。 或更确切地说-可能是在将来,这是非常令人兴奋的内容,但仍处于试验的初期阶段。 我非常怀疑MUI在这一点上是否可以使用它。

如果我错了,请纠正我,但编译后意味着具有配置,这意味着即使没有使用任何自定义样式,也必须具有用于MUI的配置文件。

我不希望被迫创建配置以仅使用MUI。 附带说明一下:在像Create React App这样自以为是的引导程序中使用它会不会很困难?

@Andarist我完全同意。 我建议开始合作,或者至少考虑参与图书馆的开发。 我对未来的发展方向感到好奇! :eyes:我认为类似编译的东西-正如您所说的-将来会很棒。 拥有更多伟大的头脑团结起来做出杰出的事情真是太棒了。

@shilangyu我不确定您的意思,因为我可能会丢失一些东西。 因此,我只想说已编译

迁移到零配置现实

我们热爱的API都可以满足您的需要-CSS道具和类名组件也可以! 我们的用户甚至不需要更改其使用组件的方式,无需继续进行零配置过程,而无需配置其捆绑程序,也不需要为服务器端渲染设置任何特定的东西。 它只是工作。

只是开始

如今,零配置立即可用,我们不会忘记明天会是什么样。 可以进行可选的CSS提取,将CSS转换为原子形式,甚至能够在整个代码库中使用CSS数据进行分析,我们正在思考一个激动人心的明天。

@MathiasKandelborg
我浏览了https://compiledcssinjs.com/ 。 它不是还在运行时css-in-js吗?
它在构建时创建css类,但是在运行时应用带有<CC>...</CC>标签的样式(使用构建时生成的css类创建样式标签)。
如果它和使用纯CSS一样快,那么它的确是未来(因为它使用CSS变量)。 感谢分享
我不知道它与情感相比有多快。

实际的零运行时库又如何呢? 我还没有看到任何人提到利纳里亚。

我们没有包括在需求中的是,从Material-UI使用者的角度来看,任何解决方案都必须为零配置。 如果我了解零运行时解决方案,那么它们会在编译时生成一些CSS。 我不必设置捆绑器以正确包含它吗?

因此,虽然零运行时间可能是最快的解决方案,但也需要格外注意。 我想拥有一个可以配置为以零运行时间运行的零配置解决方案将是理想的选择。

因此,虽然零运行时间可能是最快的解决方案,但也需要格外注意。 我想拥有一个可以配置为以零运行时间运行的零配置解决方案将是理想的选择。

Cant确实说过Compiled的当前状态,但是我与维护人员讨论了好几次,这大致就是计划-这个想法是保持对Emotion&Styled Components API的支持,因此优化编写的代码应该只是一个问题更改导入并包括转换插件或Webpack加载器。 当然,它不会处理所有可能被编写的代码(JS是疯狂的),但它应该能够处理明智的编写的代码。 如果它将无法编译的东西。 它会简单地抛出-强迫人们放弃使用它或重写代码的特定部分来辅助静态分析。

综上所述-如果您选择使用0config Emotion(或样式化组件),那么将来应该可以将Compiled作为可选优化进行改编(如果项目能够成功实现承诺的话)

@ ko-toss我认为它会在构建时编译为样式化的组件。 在运行时,然后将组件中的样式移到其应有的位置。

正如他们在网页上所说:

我们需要使用该组件的所有内容都包含在JavaScript包中。

我们将您的初始代码视为荣耀:

import { styled } from '@compiled/css-in-js';

export const ColoredText = styled.span`
  color: #ff5630;
`;

然后将其转换为编译组件:

...
...

然后在运行时将样式移动到文档的开头。

这种转换使我们可以将您的组件交付给任何消费者,而无需他们配置/设置其工具。 只需导入即可。 它功能强大,而且更重要的是,它与JS库中的当前CSS完全相同-只需一抓即可。

无法在运行时生成CSS。


我想拥有一个可以配置为以零运行时间运行的零配置解决方案将是理想的选择。

我想你打在了头上。 突然只是兴高采烈地做梦会感到乌托邦。

有一些想法需要探索,也许还有一些合作需要。 一些代码和概念对我来说有点陌生,因此我无法进行许多细节介绍。 以下是一些令我兴奋的事情:

  • 静态分析-这是一个很大的过程。 试想一下,获取有关如何使用样式解决方案的数据,获取基于X规则,约定或规范的建议,并显示可以在何处进行优化
  • 零配置-即使我会优先考虑延迟优先的更多自由(为x bundler安装插件)
  • CSS-in-JSS到纯CSS,基本上是在编译时提取样式以静态地包含它们,而无需运行时。

关于IE11支持,您如何看待统计数据? 我确信这是一件完全可行的事情。 Edge现在基于铬,并且当MS最终在其支持周期结束时安装了每个操作系统IE11时,MS最终停止了对IE的支持时,大多数企业都应该进行转换。 这确实是一个漫长的周期,但是我认为维护者也可以参与推动变更,并且保持对本质上已过时的东西的支持似乎使人们可以等待直到“转变”真正发生。

可以选择不支持IE11。 它不再是行业标准,不推荐使用。 这是一个时间问题,MUI之类的令人惊奇的事物提供的_default_支持可能会阻止这种转变。

可以选择不支持IE11。

参见https://github.com/mui-org/material-ui/issues/14420

我们不打算完全放弃对IE的支持。 默认版本可能不会针对v5中的IE 11,但我们不能选择在IE 11中根本无法使用的解决方案,或者应该是可以在构建时换出并产生相同效果的解决方案输出。

这让我开心。

我想知道是否存在用于将现有jss转换为样式/情感的代码mod?

大家好。 我借此机会深入讨论。

在当前版本中,Material UI大量使用withStyles HOC,而没有使用内部makeStyles任何动态样式(样式是依赖道具的函数)。 makeStyles (不带动态道具)的性能非常出色,如果直接使用Material UI(而不是withStyles ,甚至可以更快地使用Material UI,后者会创建不必要的包装。

我已经创建了一个基于该基准的基准,并将其部署到Vercel,以便所有代码在启用生产标志的情况下进行编译。 基准测试使用JSS库中的不同CSS渲染卡。 这里是链接:

对于100张卡片

对于500张卡片

  • makeStyleshttps : makeStyles
  • emotionhttps : emotion
  • styled-componentshttps : styled-components

2500张卡片

总体而言, emotionstyled-components在性能上非常相似。 但是, makeStyles似乎在挂载和重新渲染6-8x总体上快了2-4倍,

这种差异非常明显,特别是当我们在低功耗设备(例如我们的电话)上渲染时,那里有很多糟糕的电话。

所有这些都表示我担心材质迁移和默认情况下使用emotion这将使材质UI和使用它的网站的渲染性能降低3-5倍。 (实际上并非如此,它取决于组件;它越复杂,差异就越小)。

一些问题和值得深思的:

  • DX真的值得UX权衡吗? 甚至DX也值得商bat,因为许多人更喜欢makeStyles
  • makeStyles问题在于动态样式,这似乎可以通过实现确定性缓存ID来解决。 当前,即使道具和输出样式相同,每个组件实例也会获得其自己的ID,从而导致运行时开销,头部中的许多样式标签以及SSR性能下降。 似乎可以通过对动态样式使用哈希策略来解决问题,就像JS库中的许多其他CSS一样。 相关: https :
  • emotionstyled-components上是否还有任何改善的空间,甚至可以超越makeStyles
  • Material UI是否支持官方的JSS引擎适配器,以便开发人员可以选择它以提高性能?

我可以承受一点性能损失。

不会造成300%的性能损失,也不会有任何损失。 😅

@satazor感谢您对此进行探索。 在开始这项工作之前,我们进行了严格的性能测试,请参阅PR https://github.com/mui-org/material-ui/pull/22173了解更多详细信息(我们在ListItem组件上进行了测试),并且性能差异在在生产模式下,最多

https://deploy-preview-22173--material-ui.netlify.app/performance/list-raw/

https://deploy-preview-22173--material-ui.netlify.app/performance/list-mui/

https://deploy-preview-22173--material-ui.netlify.app/performance/list-styled/

https://deploy-preview-22173--material-ui.netlify.app/performance/list-styled-wrapper/

基于此,我们决定忽略这种差异,因为我们将获得好处(开箱即用的动态道具,已经有很大一部分开发人员使用的样式化API等)-整个摘要可以在公关描述:))

不知道基准测试中发生了什么,但是3-5倍对我来说似乎太多了,这使我想知道为什么有人会使用emotion / styled-compoenents 。看看两个基准之间的区别在哪里,以防万一我们遗漏了一些东西。 而且,在我看来,在真实的MUI组件上进行基准测试会更好,因此我们将获得更实际的数字,因此,如果您想在这一方面进行更多探索,请告诉我。 我链接的PR是一个很好的起点。

感谢您的回复@mnajdova。 没错,在Mui组件上进行测试将更加现实。 可能发生的是List组件的Mui代码是主要的慢度因素,它们之间的差异(约30ms)是与样式相关的实际渲染时间差异。 我将获取该PR的代码并将其添加到基准测试中,以查看结果。

最终会重要吗? 可能不是,但这取决于应用程序。 随着渲染代码本身更简单,当前Mui组件和样式组件之间的性能差异将增加。 举例来说,我希望看到Icon或Typography组件之间的差异增加,而Cards的差异减小。 因此,这实际上取决于应用程序以及应用程序使用的每种类型的组件数量。

这会将Material UI和使用它的网站的渲染性能降低3-5倍。

您已经创建了具有此因素的基准。 并非每个组件都会显示出这种减少。 请尽量避免得出结论,因为这种误导性信息很容易从这样一个明显的问题中传播出去。

使用devtools扩展,我看到140ms的情感挂载与120ms的makeStyles挂载。

您已经创建了具有此因素的基准。 并非每个组件都会显示出这种减少。 请尽量避免得出结论,因为这种误导性信息很容易从这样一个明显的问题中传播出去。

您说得对,请参阅我之前的评论。

您已经创建了具有此因素的基准。 并非每个组件都会显示出这种减少。 请尽量避免得出结论,因为这种误导性信息很容易从这样一个明显的问题中传播出去。

使用devtools扩展,我看到140ms的情感挂载与120ms的makeStyles挂载。

我已经将基准更新为使用actualDuration而不是baseDuration ,所以我们现在应该看到与devtools分析器中显示的内容更加内联的值。 baseDuration度量没有记忆的时间,而actualDuration相反。 请注意,此更改仅影响重新渲染的性能,现在我看到makeStyles重新渲染速度提高了6-8倍,这意味着它具有更好的缓存/存储功能吗? 但是,我没有得到您所看到的值。 您可以尝试使用更新的链接吗?

Screenshot 2020-09-22 092415
Screenshot 2020-09-22 092514

@satazor我不认为您的测试用例是等效的。 我们应该很好。

您可以尝试进行以下几项更改,以减少性能差异:

  • 安装React组件会产生成本,尤其是在渲染很多组件时。 当情感/ sc创建新组件时,makeStyles直接使用div。 在我们的表基准测试中,我体验到每个添加组件都会增加基线渲染时间,因此,如果3个级别的组件=> x3(或者为什么<MenuItem><li>慢x10)。
  • 使用makeStyles进行的演示将创建一个样式表,而情感/ sc则不会。 尝试使用带有CSS选择器的单个样式表来定位每个卡片容器中的项目。 或相反,将主要的makeStyles样式表细分为多个,每个项一个。

确实,@ oliviertassinari。 即使对于简单的组件,例如Typography ,我在这里实现的情感/样式化组件的性能似乎在1.5x-2x最大值中更高。https :

在以下位置检查生产版本和基准: https :

makeStyles的挂载速度提高1.5-2倍,重新渲染速度提高3-4倍。 这可能是需要注意的事情,但是对于更复杂的组件,我想偏差会小得多。

因此,总而言之,我不再对性能

@mnajdova这是List测试的生产版本: https : //csb-lr3sr-3zi42510w.vercel.app/?components=1000 ,复制了您提到的PR。 Codesandbox链接: https ://codesandbox.io/s/css-in-js-comparison-forked-6s4nl

makeStyles挂载速度似乎快1.7倍,重新渲染速度快2.2倍。 我没有得到您所看到的10%的差异。 难道我做错了什么?

@satazor有趣,谢谢。 我已将此基准与#22435进行了比较,以比较

import Slider from '@material-ui/core/Slider';

vs(情感)。

import SliderStyled from '@material-ui/lab/SliderStyled';

vs(样式化组件)。

import SliderStyled from '@material-ui/lab/SliderStyled';

Capture d’écran 2020-09-23 à 17 23 23
Capture d’écran 2020-09-23 à 17 25 07
Capture d’écran 2020-09-23 à 17 23 54

在这一点上,很难说出它为什么变慢了。 瓶颈可能不在样式上。 请注意,我已在开发人员模式下运行它!

我添加了两个新页面来查看Slider的WIP情感版本的性能:

一旦用于生产,其统计数据似乎类似于https://github.com/mui-org/material-ui/issues/22342#issuecomment -697540546,速度大约慢了x1.6(但CSS是完全动态的)。 请注意,您可以通过以下方式使用WIP情感版本:

Capture d’écran 2020-09-23 à 18 56 01

  • 样式化组件https: //codesandbox.io/s/preact-material-ui-test-forked-lum1y ? file =/ src/index.tsx @mnajdova对于sc,我不得不使用包裹,我无法使用CRA的模板。

Capture d’écran 2020-09-23 à 18 55 48

另外,请注意,我们知道可以通过使用makeStyles代替withStyles来使当前的JSS版本x1.1更快:#15023。

在生产模式下, @ oliviertassinari的运行速度会加快一些,但我猜差异仍然存在。 您可以单击代码沙箱上的deploy> vercel,以使用生产构建标志快速部署。

看一下makeStyles的实现方式,我看到当您只使用静态样式时它会更快:

  1. 在每次安装时,都会调用attach
  2. 如果它是该组件类型的第一个实例,则将调用stylesCreator.create ,该调用又调用fn指定的makeStyles(fn)
  3. 在其他每个实例上,由于引用计数> 0,将跳过stylesCreator.create

对于转售:

  1. 在每次重投时,都会调用attach
  2. 然后,由于引用计数> 0,将跳过stylesCreator.create ,因此根本不做任何工作。

请注意,如果要使用动态样式,则每次安装和重新渲染后,工作表都将在此处进行更新。

相反, styled-componentsemotion似乎在每个组件实例上运行我们的样式功能,这导致更多的CPU周期和内存背压。 我以为他们可以基于道具组合以某种方式进行多备忘录缓存,但是这将假定样式函数是纯函数,但事实并非如此,请考虑:

     const someContext = useContext(FooContext);

    return <div css={ { paddingTop: someContext.padding(1) } }>;

如果我的假设正确,那么静态样式生成的性能水平将很难达到makeStyles ,因为它的工作方式以及API的设计方式允许styledcss API不能。

我看到了我们可以探索的两个可能的方向:

  • 在第一期的描述中,我们仅在Material-UI的动态支持下对性能进行了基准测试。 我们可以为静态案例(v4使用什么)添加一个条目。 我们也可以为react-jss提供静态和动态支持。 这应该有助于我们了解可用的样式引擎选项的范围。
  • 我们可以调查瓶颈在哪里。 我们可以想象有一个js适配器,就像样式组件一样,看看性能是否更好。 动态版本的JSS应该会更糟,但是我们可以将其与静态版本进行比较。 也许它来自无样式的抽象。
  • 我们可以认为,放慢速度是解锁动态样式和未样式化值得花费的价格。 那就是如果您要呈现一个长长的列表,则将使用虚拟化或依靠嵌套的CSS选择器。
    事实证明,情感和样式化组件可提供灵活性并足够快,而业界对此也是如此,React也是如此。

如果不知何故emotion公开了一个useCss钩子,就像在https://github.com/emotion-js/emotion/issues/1321https://github.com/emotion- js / emotion / issues / 1853 ,我们可以保留makeStyles API并因此保留“静态CSS”的好处。 但是,我们将继续在所有地方使用静态CSS来提高性能,这并不是那么“干净”,但这就是我们在v4中所做的。

实际上,使用ClassNames API,我认为我们现在可以进行withStyles的移植,这将保留静态CSS性能和情感所具有的动态CSS的良好性能。 如果const css = useCss()存在,那么创建useStyles API端口也很简单。

保留withStyles + makeStyles API的主要优点是:

  • 材料要做的迁移实际上是没有的,我们只需要将这两个功能移植即可。
  • 已经在Material UI之外使用withStylesmakeStyles的用户根本不需要迁移。 他们将免费获得改进动态CSS性能的好处。
  • 不需要其他逻辑来保留classes + CSS API。 使用styled我们需要手工或使用util创建全局className
  • 在此策略中, useCss是我们的JS解决方案中CSS的适配器函数,而不是styled
  • 为了支持JS解决方案中的其他CSS,他们需要提供一个useCss挂钩或类似的挂钩。 理想情况下,我们可以执行webpack / babel别名来切换它们,就像styled

我们在https://twitter.com/olivtassinari/status/1309247827839680512中进一步探讨了性能问题

  • 本机:7.71ms
  • v5无样式:20.89ms
  • v4:29.93ms
  • v5:37.37ms
  • antd:53.48ms
  • 脉轮:64.67ms

https://codesandbox.io/s/slider-comparison-forked-jziv6?file=/src/App.js…

抱歉,我在这么晚的讨论中打扰了您,但我对您没有密切关注styled-jsx感到惊讶

他们的清单完全符合您的要求:

  • Works服务器和客户端
  • 全面的CSS支持,无权取舍
  • 运行时大小仅为3kb(压缩后为12kb)
  • 完全隔离:选择器,动画,关键帧
  • 内置CSS供应商前缀
  • 快速,最少和有效的移栽(见下文)
  • 非服务器渲染时的高性能运行时CSS注入
  • 面向未来:等同于服务器可渲染的“ Shadow CSS”
  • 源地图支持
  • 动态样式和主题支持
  • 通过插件进行CSS预处理

我要注意一个事实,它几乎是一个影子CSS标准API 。 因此,通过删除jsx属性,您可以很好地转换到将来可以在普通浏览器中正常运行的Web组件。

是的,我知道它可能不是最受欢迎的一种。
但我只想指出,Flash在几年前非常流行。
但是最终它变得不兼容Web标准,并且现在已经有了SVG。
仅出于记录目的,SVG标准在Flash统治整个行业时就已经存在了很长时间。
我只是将历史事件看作是一个很好的教训,并会尝试发现流行是防弹可维护和未来证明的最后一个指标。

@mifrej我个人对此有不好的经验: https

我们在https://twitter.com/olivtassinari/status/1309247827839680512中进一步探讨了性能问题

  • 本机:7.71ms
  • v5无样式:20.89ms
  • v4:29.93ms
  • v5:37.37ms
  • antd:53.48ms
  • 脉轮:64.67ms

https://codesandbox.io/s/slider-comparison-forked-jziv6?file=/src/App.js…

您是否尝试过将babel插件用于情感/样式组件? 它对时间有影响吗?

对于现有MUI组件上可用的classes道具,与JSS相比意味着什么? v5迁移将如何寻找广泛利用此道具的现有用户?

我们设想人们改用以下语法: https: //next.material-ui.com/components/slider-styled/#unstyled -slider基本上,类被替换为组件中每个插槽可用的类选择器。 您还可以查看自定义示例: https: //next.material-ui.com/components/slider-styled/#customized -sliders

作为优势,您可以只使用道具,并根据它们应用动态样式。

我们设想人们改用以下语法: https: //next.material-ui.com/components/slider-styled/#unstyled -slider基本上,类被替换为组件中每个插槽可用的类选择器。 您还可以查看自定义示例: https: //next.material-ui.com/components/slider-styled/#customized -sliders

作为优势,您可以只使用道具,并根据它们应用动态样式。

我喜欢这个API! 这是一个非常可喜的变化,它在样式引擎中看起来非常不错。

v5 ,如果我没记错的话,JSS编译器会破坏那些类名,而您不能可靠地将它们作为目标? 但是现在看来它们会出于定位目的而公开吗? 🙌另外,CSS优先级存在问题。 这些问题可以通过这种新方法解决吗? 感谢您为这个重构工作!

@ConAntonakos正是这些类可以同时针对组件的未样式化和样式化版本。 调用样式的顺序确保了新样式将获胜,当然,如果特异性相同:)

在v5之前,如果我没记错的话,JSS编译器会破坏这些类名,而您不能可靠地将它们作为目标?

您已经可以在v4中定位它们。

这些类基本上由组件中每个插槽可用的类选择器代替。

是“基本”替换还是实际替换? 我以为我们决定保留一些旧的API,以减少重大更改的次数。

我以为我们决定保留一些旧的API,以减少重大更改的次数。

我们决定为theme.components.overrides保留相同的API-以相同方式在主题工作中定义的替代。

对于实例重写,我们现在使用styled方法和类选择器,这就是为什么不再支持classes道具的原因。 开发人员现在可以以更灵活的方式执行此操作。

开发人员现在可以以更灵活的方式执行此操作。

听起来这是个小问题,因为有替代方法,但是迁移成本很高。 迁移计划如何?

开发人员仍然可以使用主题替代,如果他们只是将实例替代移动到嵌套的ThemeProvider则根本不需要更改定义的样式,因为这两者之间的结构是相同的(这并不完美) ,但是如果他们要进行增量升级,则是一种方法)

另一方面,我们仍然可以轻松地支持class属性,但是在那种情况下,我们不能保证是否在同一组件上使用了class + styled的组合才应该获胜。 我们是否应该至少在组件的样式版本上向后移植类的支持?

我可能在此线程的整个过程中都错过了这个-我的classes问题的另一个相关问题。 可能会有什么样的“正确性”保证?

例如,我编辑了滑块示例:

const StyledSlider = styled(SliderUnstyled)`
  & .MuiSlider-raill {
    display: block;
    position: absolute;
    width: 100%;
    height: 2px;
    border-radius: 1px;
    background-color: currentColor;
    opacity: 0.38;
  }
)

您会发现我不小心拼错了MuiSlider-rail 。 以前使用classes会有类似classes.rail ,如果我拼写错误的属性,我会收到运行时警告,样式表中不存在classes.raill 。 我相信主题有相同的行为?

我能想到的classes API的优点:

  1. 与在子级之间泄漏的全局CSS选择器相对立:例如在.css-e7ylz8 .MuiTreeItem-group 。 您不能保证该组件不会将样式应用于子组件(这不是您所期望的效果,这是一个惊喜!)。 我们的组件可能不错,因为我们会小心。
  2. 使处理门户变得轻而易举: https
  3. 如果未定义样式规则,则$styleRule语法会发出警告。
  4. 允许自定义使用的类名。 当前解决方案是使用componentsProps道具。 我们合并类名。

在另一个世界中,我们将:

一种。 允许使用样式化的组件选择器来求解1.和3.。
b。 公开classes API,以实现向后兼容。
C。 为了得到一个。 和b。 要工作,我们将需要扁平化内部编写组件样式的方式。 x样式的组件,而不是1样式的根。 但是⚠️具有性能暗示。

我们真的需要这样做吗?


我看了jQuery UI的classes道具的历史。 我可以找到两个问题: https : //bugs.jqueryui.com/ticket/8928和初始提交: https :

我们设想人们改用以下语法: https: //next.material-ui.com/components/slider-styled/#unstyled -slider基本上,类被替换为组件中每个插槽可用的类选择器。 您还可以查看自定义示例: https: //next.material-ui.com/components/slider-styled/#customized -sliders

作为优势,您可以只使用道具,并根据它们应用动态样式。

哇,这是有史以来最好的事情。
无样式或无头组件将是定制的最佳选择(我认为是mui的批评家之一)。
这不是修复imo的小事,而是MUI的加成。

PS:我记得过去很难定制一些组件
PS2:您是否看过https://github.com/modulz/stitches

您会发现我不小心弄错了MuiSlider-rail。 以前使用类时,会有诸如classes.rail之类的东西,如果我拼写了错误的属性,则会收到运行时警告,样式表中不存在classes.raill。 我相信主题有相同的行为?

@ianschmitz除了建议使用样式化组件选择器的选项@oliviertassinari之外,我们还有另一个选择,它是为所公开的类公开常量。 也许像这样:

import { sliderClasses } from '@material-ui/core/Slider';

const StyledSlider = styled(SliderUnstyled)`
  & .${sliderClasses.rail} {
    display: block;
    position: absolute;
    width: 100%;
    height: 2px;
    border-radius: 1px;
    background-color: currentColor;
    opacity: 0.38;
  }
)

它与classes.rail运行时警告不同,但应有助于防止拼写错误的类。

@mnajdova我们也可以考虑使用eslint插件。

关于classes道具的支持-为了使我们能够可靠地做到这一点,我们将必须为核心组件的每个部分(插槽)创建组件。 例如,对于Slider ,我们将需要为rail,track,mark,mark label,thumb和value标签创建组件。 这将使我们能够直接在那些组件上指定样式,而不是使用类来增加特异性。 这些更改可以在此PR上找到-https: //github.com/mui-org/material-ui/pull/22893

有了这些变化,我们创建了一个codesandbox,可以比较相比V4,本土风格,无样式,以及其他两个竞争的图书馆这个新的更新Slider组件的PERF - https://codesandbox.io/s/滑块比较多个组件2tytc?file = / package.json

如果我们比较这些与PERF只有一个组成部分,并使用类选择为它的部件的PERF - https://codesandbox.io/s/slider-comparison-forked-jziv6?file=/src/App.js我们将注意到,每个插槽添加组件的性能下降20%😢

生产版本:

老实说,我目前不知道添加这种向后兼容性是否更好。

这些是支持classes实际用例,还是只是为了简化升级?
我们是否可以仅出于缓解迁移路径而降低20%的性能?
是否有一些我们看不到的替代方案,可以帮助我们在不支付性能成本的情况下完成这两项工作?

@ianschmitz @ eps1lon @oliviertassinari和其他人:)对此有什么想法吗?

只要我们可以使用TypeScript定义和使用主题和样式,与损失20%的性能相比,我不介意花费时间进行迁移

我通常很好奇,如果我不理解底层设计,请原谅我,但是classes是JSS的API吗? 如果API设计正在从JSS切换到样式化的组件,那么继续支持classes是否有意义?

这些是支持classes实际用例还是仅仅是为了简化升级?
我们是否可以仅出于缓解迁移路径而降低20%的性能?
是否有一些我们看不到的替代方案,可以帮助我们在不支付性能成本的情况下完成这两项工作?

如果我错过了所提出的API的任何内容,我们深表歉意,但在IMO中,我在组织中最常看到的用例是MUI使用的基础样式系统的抽象。 是的,我猜classes有点像@ConAntonakos提到的“ JSS API”,但对消费者而言并不重要。 作为消费者,我可以使用CSS偏好技术( classes吗?今天有什么限制)。 我们有许多使用以下产品的产品:

  • 香草CSS文件
  • SCSS
  • JSS

取决于这些团队的需求和偏好。

如果您使用某种CSS-in-JS,则导出类名会有所帮助,但是对于那些不是CSS-in-JS的人有什么想法?

回覆。 性能百分比为20%,我同意这可能不是一个可以接受的折衷方案。 归根结底,你们应该为大多数社区做最好的事情。 只提供我的想法😄

我从未想过的一个希望是,material-ui将是本机兼容的。 如今,许多项目都是跨平台的,拥有统一的样式解决方案为跨平台组件提供了很多优势。 我们最终在网络侧使用material-ui滚动了自己的页面,在本机侧使用了react-native-paper并在material-ui API上进行了标准化。 我很想了解这个新的样式解决方案是否可以在react-native上使用(某些/全部)Material UI组件? 组件中的任何窗口引用显然都是一个阻止程序,但是样式本身也支持本机,不是吗?

到目前为止,@ mschipperheyn react-native还是没有目标。 这是+ 5%的使用潜力(增长1个月)和+ 50%的精力(猜测)。 机会成本确实很高,并且没有关于如何货币化的明显方向(在Ionic的模型之外)。 另外,请记住,颤动似乎已经吸引了许多对本机目标做出反应的听众。

现在v5处于Alpha版本中,是否可以解决此问题? 特别是,样式解决方案是否仍基于JSS? 我们已经看到了与JSS相关的重大性能问题,因此一直热切期待新的解决方案。

@zzzev这本身不是问题。 这是一个RFC(评论请求)线程。

我对您正在谈论的哪些实质性性能问题以及从JSS进行改进会产生疑问。 因为我看到的方式是,如果您遇到性能问题,那可能不是样式,而是样式的实现方式,即,通过使用更少的处理能力以另一种方式编写样式,可以实现相同的结果。

至少我没有关系到从JSS到Emotion(在此线程中显示为_最有可能的_性能会有所下降)将如何改善任何方面。

我的理解是,情感会轻微影响静态样式的性能,并会改善动态样式的性能-但这也许是不正确的? 这个线程中有很多不同的数字,很难将其协调成一张绩效图(显然,这在很大程度上取决于个人的情况)。

当您说我们应该以不同的方式来编写样式时,是否意味着要避免使用动态样式? 还是我们应该考虑其他最佳实践?

@zzzev在第一部分上是正确的,在第二部分上是不正确的(除非您将不受支持变为支持是无限的性能提升🙂)。

Emotion支持动态样式,但以牺牲静态性能为代价。

我很困惑; 当前的/ v4 makeStyles中没有动态样式吗? 例如这种模式

我很困惑; 当前的/ v4 makeStyles中没有动态样式吗? 例如这种模式

有,但是有一个著名的性能问题。 我的团队远离ATM

我只是讨厌组件样式
jss很好,但是在调试,性能方面仍然存在一些问题,还有一些仍未解决的错误,例如像&:after这样的嵌套

这是我为react-native和react-native-web建立的软件包
https://www.npmjs.com/package/@material-native-ui/theme -provider

我想要这样的东西(它是在RN和RNW之上构建的)

那么对于与Material UI v5一起使用的推荐样式解决方案是否有结论? 似乎有意摆脱目前基于@material-ui/styles JSS。 还是将@material-ui/styles重构为以styled-components等其他样式解决方案为基础?

那么对于与Material UI v5一起使用的推荐样式解决方案是否有结论? 似乎有意脱离目前基于@ material-ui / styles构建的JSS。 还是将@ material-ui / styles重构为基于其他样式解决方案(例如,样式组件)?

@ matthewkwong2我们不会在新样式的引擎中采用@material-ui/styles包,它将继续支持jss。 在v5中,它将与其余代码库隔离,我们计划在v6中将其删除,以帮助过渡到新的样式引擎。

对于v5,我们将提供有关样式解决方案的全新实践,例如sx道具和styled实用程序,我们仍在处理有关此问题的文档。

此外,v5仍将支持主题替代和变体。

对于v5,我们将提供有关样式解决方案的全新实践,例如sx prop和styled实用程序,我们仍在处理有关此问题的文档。
此外,v5仍将支持主题替代和变体。

因此,如果我正确理解的话,对于单个组件的样式,建议使用sxstyled代替makeStyles

但是主题(即createMuiTheme )呢? 我相信那部分也是建立在JSS上的吧? 现在推荐的创建主题的方法是什么(即主要目的是定义全局样式)?

我们仍然保留用于创建主题的相同结构,只是期望组件的值覆盖和变体遵循情感/样式化组件的语法。 主题的创建方式没有任何变化,API完全相同,相同的主题上下文也可用于新样式的引擎。 @ matthewkwong2有意义吗?

到目前为止,@ mschipperheyn react-native还是没有目标。 这是+ 5%的使用潜力(增长1个月)和+ 50%的精力(猜测)。 机会成本确实很高。 另外,请记住,颤动似乎已经吸引了许多对本机目标做出反应的听众。

我不想让我们切入正切,但我想推论其中的一些基本原理。

  • 过去,构建RN应用程序时最难处理的事情之一是Material Design。 实际上,这是一个足够大的问题,它可能潜在地决定是否要打扰构建移动应用程序。 我听说使用一个有前途的新库会更好一些。 但是我怀疑,如果MUI参与其中,它是否会像它一样有前途。 也许只有我一个人,但是我可以看到跨平台的MUI确实增加了RN的使用率。 我知道这只是react-dom用法的一小部分,但是web庞大,而react-dom在现代web框架中占主导地位。 即使本机使用量相对较小,作为使用它的绝对人数,仍然可以有相当多的人使用。 对当前MUI用户进行的民意测验可能比npm统计数据更好。
  • 我知道我不了解问题,但我不太愿意购买Flutter接管React Native。 流量比较并不是比较的好方法。 它受许多混杂因素的影响(Flutter较新,因此更多的人已经了解RN,而无需参考文档; Flutter的文档可能对重新引用增加其流量更为有用;某些RN的文档阅读流量也可能会不断增加)改为博览会)。 与Google趋势进行比较时,这种有一定缺陷的方法几乎是一个更好的衡量标准,而且相当平均。 我个人知道Flutter遇到了一些麻烦事,RN在下一次客户说他们想要移动应用程序时仍然更有希望。
  • 在使MUI与React Native一起工作时,JSS是最大的问题之一(实际上可能最大的问题)。 我知道仍然会有一些复杂的因素,但是恕我直言,情感转换至少在实验上已经消除了使MUI在RN中工作的2/3的困难。

转向情感可能消除了使MUI在RN中工作的难度的2/3

我们期待着您的POC😄

我们期待着您的POC😄

如果有机会,我很乐意尝试一下。 但是人们通常不会为维护者不感兴趣的事情而制作POC。 当当前的气氛可能最终会被抛弃时,毫无意义地建立某种东西。 因此,为什么我要不放弃将RN的价值或RN的价值视为未来的可能性。

两个问题:

  1. 您可以在没有HOC的情况下使用新的样式解决方案吗? 我一个人喜欢MUI当前拥有的React钩子API ...不确定样式化的语法是否也可以用作HOC,但是在摆脱HOC方面,这将是失败的努力(React库中几乎所有地方)。
  2. classes支持大多数组件是否仍受支持(它将为用户提供哪种样式解决方案提供充分的灵活性)?

fast-refresh默认情况下在create-react-app v4中启用。 我们应该添加快速刷新支持作为新要求吗?

用盖茨比尝试一下。 当我执行import { Link } from '@material-ui/core'我得到了:

Can't resolve '@emotion/core' in 'node_modules/@material-ui/styled-engine'
File: node_modules/@material-ui/styled-engine/index.js

Can't resolve '@emotion/styled' in '/node_modules/@material-ui/styled-engine'
File: node_modules/@material-ui/styled-engine/index.js

当更改为import Link from '@material-ui/core/Link'问题消失了。

如果我安装@emotion/styled @emotion/core ,则会得到:

无法解析'/ node_modules / @ emotion / styled / dist'中的'@ emotion / react'

然后我安装@emotion/react

出现运行时错误。

Error: The `@emotion/core` package has been renamed to `@emotion/react`. Please import it like this `import { jsx } from '@emotion/react'`.
./node_modules/@emotion/core/dist/emotion-core.cjs.dev.js
node_modules/@emotion/core/dist/emotion-core.cjs.dev.js:3

涉及的软件包版本:

    "@emotion/core": "^11.0.0",
    "@emotion/react": "^11.0.0",
    "@emotion/styled": "^11.0.0",
    "@material-ui/core": "^5.0.0-alpha.15",
    "@material-ui/lab": "^5.0.0-alpha.15",

安装v10版本的Emotion软件包

哦11现在是“最新”版本,所以我认为mui需要升级或记录该文件

哦11现在是“最新”版本,所以我认为mui需要升级或记录该文件

我们通过peerDependencies版本范围对其进行了记录。 我们没有在安装说明中明确提及它,因为我们计划将其更新到v11。

友情提醒,这只是几天前的alpha和情感11。 作为早期采用者,您应该期望有一些粗糙的边缘。

大家好,我是新来的,当时我正在查看material-ui css解决方案,并遇到了这个问题。
只需为此付出2美分,我就建议Linaria https://github.com/callstack/linaria。
这是一个零运行时库,具有CSS提取和CSS变量作为React道具。

希望这对RFC helps有帮助。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

ghost picture ghost  ·  3评论

mattmiddlesworth picture mattmiddlesworth  ·  3评论

revskill10 picture revskill10  ·  3评论

iamzhouyi picture iamzhouyi  ·  3评论

chris-hinds picture chris-hinds  ·  3评论