Styled-Components与SASS(SCSS)或LESS的比较

50
我发现了一个ReactJS Boilerplate,它有很好的声誉并且由社区推动。样式部分更强调styled component CSS,但并没有停止使用传统的CSS样式方法。虽然这引起了我的兴趣,但是什么使得Styled-Component CSS脱颖而出,为什么需要采用它呢? 我对Styled component CSS的理解:
  1. 组件驱动思想。你的CSS现在也是一个组件。- 这非常酷!
  2. 按需加载,懒加载CSS。
  3. 主题提供程序、皮肤、模块化和动态性 - 这也可以通过其他库实现。
  4. 服务器端构建您的组件DOM及其样式。
我的问题是:
  1. 浏览器已经演变到将CSS与Javascript分开解析,为什么我们要偏离这一点并将所有内容都放在Javascript中?

  2. Styled-component CSS将其Javascript库发送到客户端,实际上是在运行时解析样式并将其放置在<style />标签中,当每个组件按需加载时。这意味着额外的负载和逻辑最终会导致浏览器执行周期。为什么需要这样做?

    (通过上述问题,我的意思是对于每个加载的组件,相应的CSS都会被计算、创建并插入到头部,通过style标签/多个样式标签 - 重新发明CSS解释器)

  3. 连续计算的样式文本通过<style />在头部标签中引起浏览器回流/重绘吗?

  4. 我从中获得了哪些性能优势?

  5. 使用像Post-CSSSCSS classname hashing这样的附加库/选项进行动态类名,这几乎解决了每个人都提出的问题。为什么还要使用SC?

社区,请为我澄清或纠正我的错误。


有一些很好的文章讨论了当CSS样式被修改时,重新绘制或DOM重排如何对浏览器的性能产生影响。


7
在styled components中,值得一提的是CSS失去了C - 层叠。 - Matthew Barbara
1
@MatthewBarbara - 这可以被视为一种收益,因为重点是将组件的样式相互隔离。在内部,每个组件仍然是普通的 CSS(具有级联)。 - vsync
2个回答

30

我已经使用SCSS (SASS)多年了,也在一些大型项目中使用Styled-Components

我喜欢两者,但Styled-Components对我来说感觉像是向前迈出的一步:

Styled-Components - 优点

  1. 完全隔离样式;在团队合作时可以防止潜在的错误,因为一个团队成员永远不能覆盖另一个成员的样式。(除非多个地方共享同一个styled component)
  2. 不需要手动处理类名,因为它们会自动生成(在我看来,选择组件比选择类名要容易得多)
  3. 我发现在JSX文件本身中使用CSS更容易(与我多年来的判断相反)

  4. 轻松在样式中使用javascript变量(消除了2组主题变量的需求)

Styled-Components - 缺点

  1. 每个样式组件都是另一个包装函数,而许多样式组件意味着更多的函数,这意味着不太高效,因为所有代码都需要“编译”等。
  2. 最大的缺点:样式更改需要重新编译捆绑包,应用程序状态可能会重置。

这些缺点只在某些情况下才被视为缺点,而不一定是全部情况。


SCSS/LESS的优点可以被看作是上面列出的缺点的相反面,但还有一些缺点,例如混合和使用变量时开发速度更快(依我之见)。定义本地选择器变量可能会变得“丑陋”:

比较这些简化的示例:

SCSS示例:

.icon{
  $size: '20px';
  width: $size;
  height: $size;
  margin-left: $size/2;
}

Styled-Components 本地作用域示例:

const Icon = styled.i(props => {
  const size = 20; // easier to use Number instead of String for calculations 
  return `
    width: ${size}px;
    height: ${size}px;
    margin-left: ${size/2}px;
`});

显然,该变量可以在Icon样式包装器外部定义,然后在内部使用,但这并不会使其隔离,因为styled-components的CSS可能由样式化的子组件组成,看起来更像CSS:

const Header = styled.header`
   > ul{
     ...
   }

   li{
     ...
   }

   img{...}

   navigation{...}
`

并不总是需要将每个HTML元素提取到自己的styled组件中。这样做主要是为了那些可能在整个应用程序中重复使用的组件。

关于SASS混合,它们可以转换为JavaScript函数,因此在这里使用SASS没有太多优势。

总的来说,使用Styled-Components很有趣和容易上手,但它会导致样式与框架/组件之间耦合度更高,并且显然会对性能产生一定影响(虽然不会真正使您变慢)。


我在这篇文章中更详细地介绍了使用Styled-Components的高级变量。 - vsync

11
浏览器已经演变成可以单独解析CSS而不是与Javascript一起解析,为什么我们要偏离这个方向,把所有内容都放在Javascript中呢?
当你混合使用Javascript和HTML(即JSX)以及CSS(JSS或其他),然后将其作为一个模块放入单个文件中,你的组件就会变成一个实心模块。你不再需要将样式保留在单独的文件中。
然后,神奇的事情发生了:因为JSX是原始数据的纯函数,返回"HTML"(实际上并不是),同样地,CSS-in-JS也是原始数据的纯函数,返回"CSS"(同样也不是)。从这一点出发,我认为值得阅读关于JSXCSS-in-JS的文章。
Styled-component CSS将其javascript库发送到客户端,实际上在运行时解析样式,并在每个组件按需加载时将其放入<style />标签中。这意味着额外的负载和逻辑最终会导致浏览器的执行周期。
不仅在运行时如此。因为CSS-in-JSS只是一个处理数据并返回CSS的函数,所以你可以在任何平台上使用它。拿Node来举例,添加SSR,你就可以在响应主体中传送style元素,因此就像在获取CSS时一样进行解析。
为什么需要这个呢?

因为在开发中很方便,就像React或Redux、jQuery以及其他任何库一样,但这也会导致网络负载和浏览器性能问题。

使用库是为了解决问题。如果似乎没有问题,那么为什么还要使用库呢?

通过标签中的<style />进行持续计算样式文本是否会导致浏览器重排/重绘?

很多东西会引起重排

浏览器很聪明。如果样式没有改变,它们甚至不会尝试重新绘制。但这并不意味着它们不会计算差异,这会消耗CPU时间。

样式(重新)计算的范围和复杂性有很好的介绍,值得深入了解。


6
imo jsx 与虚拟 DOM 密不可分,这是性能的优势。我非常喜欢 Styled-components 中 JavaScript 驱动和在 js 中编写 CSS 的部分,开发时的 CSS 组合变得很酷,但我不能以牺牲最终性能为代价。持续的样式更改会导致不必要的重排。浏览器解析静态 CSS 树,你无需在运行时担心其余部分,只需要处理 JS 模型、逻辑及 JSX,来展示我在屏幕上的视觉数据。在运行时对这些视觉元素进行样式设计,在我看来是不必要的,除非有需要。 - NiRUS
2
因为它很方便。因为开发人员和开发时间的成本比优化更高。因为如果它继续卡顿,性能瓶颈无疑会被解决。因为浏览器只会变得更快、更智能。因为在未来,我们将只通过网络加载程序,并探索软件生态系统,而不是网站。因为全局样式规则需要覆盖才能有所不同。我不知道。我真的不知道。但正如@Fleischpflanzerl所说,如果库对你没有解决问题,就不要使用它。 - Paul-Sebastian Manole
@brokenthorn 我并不反对使用任何库,但我的观点是,这个库是否比针对与Styled Components相同问题陈述的SASS或LESS更值得使用。 - NiRUS
不,它们并不会。SASS/LESS旨在修复仍然是CSS的CSS。SC是HTML和CSS的封装片段。CSS不再层叠,您也不需要整个CSS框架。 - Paul-Sebastian Manole
@brokenthorn,那么我想你需要完全阅读这篇激励文章(https://www.styled-components.com/docs/basics#motivation),其中明确指出了“styled-components是对如何增强CSS以用于React组件系统进行思考的结果”的开头一句话。当然,他们的目标是增强CSS。 - NiRUS
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接