样式组件与SASS(SCSS)或LESS

时间:2017-10-14 16:52:38

标签: css reactjs sass styled-components reflow

我遇到了一个ReactJS Boilerplate,它有很好的代表并且是社区驱动的。 样式部分更多地强调了样式化组件CSS,但从未停止过切换到传统的CSS样式方法。虽然这引起了我的兴趣,但是什么使得Styled-Component CSS脱颖而出,为什么需要采用它。

我对Styled component CSS的理解:

  1. 组件驱动的思想。您的CSS现在也是一个组件。 - 这很酷!
  2. 加载您需要的内容以及何时需要,有点懒惰的CSS
  3. 主题提供者,皮肤,模块化和动态 - 这也可以通过其他库来实现
  4. 组件DOM的服务器端构造及其样式。
  5. 我的问题是:

    1. 浏览器的发展是为了与Javascript分开解析CSS 解析,为什么我们试图偏离这一点并适应所有人 的Javascript?

    2. Styled-component CSS将其javascript库发送到客户端, 它实际上解析了运行时的样式,并在每个组件按需加载时放入<style />标记内。这意味着额外的负载 和逻辑最终有助于浏览器的执行周期。 为什么需要这个?

      (通过上面的问题,我的意思是每个加载相应CSS的组件都是通过style标签/多个样式标签计算和创建并插入头部的 - 重新发明CSS解释器) < / p>

    3. 是否通过<style />连续计算样式文本 head标签导致浏览器重排/重绘?

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

    5. 社区,请为我清空或纠正我,如果我错了。

      一些关于重绘或DOM的好文章重新介绍了修改CSS样式时浏览器的性能代价。

3 个答案:

答案 0 :(得分:1)

  

浏览器的发展是为了解析CSS与Javascript解析分开,为什么我们试图偏离这一点并适合所有Javascript?

当你混合使用Javascript和HTML(即JSX)以及CSS(JSS或其他)时,可以使组件成为适合单个文件的可靠模块。您不再需要将样式保存在单独的文件中。

然后,功能魔术发生了:因为JSX是原始数据的纯函数,它返回&#34; HTML&#34; (不是真的),同样的方式,CSS-in-JS是纯函数或原始数据返回&#34; CSS&#34; (也不是真的)。从这一点来说,我认为它值得reading about JSXalso about CSS-in-JS

  

Styled-component CSS将其javascript库发送到客户端,它实际上在运行时解析样式,并在每个组件按需加载时放入<style />标记内。这意味着额外的负载和逻辑最终会导致浏览器的执行周期。

不仅在运行时。因为CSS-in-JSS只是返回CSS的数据的函数,所以您可以在任何平台上使用它。选择Node,添加SSR,并在响应正文中将style元素传递给浏览器,因此解析就像在原始的CSS传递中一样。

  

为什么需要这个?

因为它在开发方面很方便,就像React或Redux一样,就像jQuery一样,就像任何其他lib一样,它会带来网络负载和浏览器性能成本。

你拿一个图书馆是因为它解决了一个问题。如果似乎没有问题,为什么要使用库,对吧?

  

在head标记中通过<style />进行连续计算的样式文本会导致浏览器重排/重绘吗?

so many things that force reflow

浏览器很聪明。如果款式没有改变,他们甚至不会尝试重新粉饰。这并不意味着他们不计算差异,这会花费CPU时间。

the scope and complexity of style (re)calculations有一个很好的介绍,为了更深入地理解这个主题,真的值得一读。

答案 1 :(得分:-1)

我已经使用SCSSSASS)多年了,并且也已经在一些大型项目中使用Styled-Components

我俩都爱,Styled-Components对我来说就像向前迈进了一步。

样式化的组件-优点

  1. 完全样式隔离;防止团队工作中潜在的错误,当一个团队成员永远无法覆盖另一个团队的样式时。
  2. 不再需要手动处理自动生成的类名
  3. 我发现在 JSX 文件本身中使用 CSS 更加容易(我反对这个想法已有很多年了)

    < / li>
  4. 能够轻松使用样式内的javascript变量

样式化的组件-缺点

  1. 每个样式组件都是另一个包装函数,许多样式化的组件意味着更多的功能,这意味着效率较低,因为所有代码都需要“编译”,依此类推。
  2. 最大的缺点:更改样式需要重新打包捆绑软件,并且应用程序的状态可能会重置。
  

只能在某些情况下这样查看缺点,而不能查看   一定是全部。


SCSS / LESS 优点可以被视为与上面列出的缺点相反,但是在使用变量(IMHO)时还具有一些缺点,例如混合和更快的开发。定义局部选择器变量可能会很“丑陋”:

比较以下简化示例:

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样式的包装器之外定义,然后在内部使用,但这不会使它孤立,因为样式组件CSS可能由样式化且看起来更多的子组件组成像CSS:

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

   li{
     ...
   }

   img{...}

   navigation{...}
`

并非总是希望将每个单独的HTML元素提取为其自己的样式组件。它主要是针对在整个应用中重复或可能重复的组件完成的。

关于SASS混合,可以将它们转换为javascript函数,因此这里的SASS没有太大优势。

总的来说,使用样式化组件很有趣且容易,但副作用是样式与框架/组件之间的耦合更紧密,并且显然会降低性能(实际上并不会降低您的速度,但仍然)。

答案 2 :(得分:-1)

您提到的Google重排文章中的四个关键点中的两个是:

  • 最小化CSS规则,并删除未使用的CSS规则。

  • 避免使用不必要的复杂CSS选择器-特别是后代选择器-需要更多的CPU能力来进行选择器匹配。

如果使用得当,它们是在React中使用样式化组件的副产品。

使用传统的样式设计方法,尤其是在大型团队中,未使用/重复的CSS规则趋于堆积。开发人员可能不知道可以使用的给定规则,因此会添加一条新规则。否则,一个组件将被删除,而正在使用的CSS可能不会被删除,因为他们不确定是否在其他地方使用了它。

并且由于样式倾向于使用Styled Components / CSS-in-JS隔离到一个组件,因此我们通常避免使用那些糟糕的后代选择器。

此外,当我认为“正确使用”时,我的意思是不要在整个应用程序中散布样式,而是构建一个包含应用程序使用的所有样式化基础组件的组件套件,可能实现一个主题。

有一个使用样式化组件以这种方式隔离CSS的React / React-Bootstrap example on Code Sandbox,还有关于CSS-Tricks的文章detailing the approach。它主要侧重于样式化组件如何帮助您从快速,肮脏的React-Bootstrap实现迭代到最终重构React-Bootstrap依赖关系的自定义主题。但是,这对于显示如何使用它来实现Google文章中提到的这两个关键回流优化也很有用。

另外两点与CSS与CSS-in-JS讨论无关:

  • 减少不必要的DOM深度。 DOM树中某一级别的更改会导致该树的每个级别的更改-一直到根,一直到修改节点的子级。这会导致花费更多的时间进行回流。

  • 最小化CSS规则,并删除未使用的CSS规则。 如果您进行复杂的渲染更改(例如动画),请不要进行此操作。使用绝对位置或固定位置来完成此操作。

无论采用哪种样式,您都应接受建议。但是,我认为前两个可以通过我描述的方式使用样式化组件来覆盖,即创建一个组件工具包并将所有样式保留在其组件中。然后使用该工具包构建您的应用。