我遇到了一个ReactJS Boilerplate,它有很好的代表并且是社区驱动的。 样式部分更多地强调了样式化组件CSS,但从未停止过切换到传统的CSS样式方法。虽然这引起了我的兴趣,但是什么使得Styled-Component CSS脱颖而出,为什么需要采用它。
我对Styled component CSS的理解:
我的问题是:
浏览器的发展是为了与Javascript分开解析CSS 解析,为什么我们试图偏离这一点并适应所有人 的Javascript?
Styled-component CSS将其javascript库发送到客户端,
它实际上解析了运行时的样式,并在每个组件按需加载时放入<style
/>
标记内。这意味着额外的负载
和逻辑最终有助于浏览器的执行周期。
为什么需要这个?
(通过上面的问题,我的意思是每个加载相应CSS的组件都是通过style
标签/多个样式标签计算和创建并插入头部的 - 重新发明CSS解释器) < / p>
是否通过<style />
连续计算样式文本
head标签导致浏览器重排/重绘?
我从中获得了哪些性能优势?
社区,请为我清空或纠正我,如果我错了。
一些关于重绘或DOM的好文章重新介绍了修改CSS样式时浏览器的性能代价。
答案 0 :(得分:1)
浏览器的发展是为了解析CSS与Javascript解析分开,为什么我们试图偏离这一点并适合所有Javascript?
当你混合使用Javascript和HTML(即JSX)以及CSS(JSS或其他)时,可以使组件成为适合单个文件的可靠模块。您不再需要将样式保存在单独的文件中。
然后,功能魔术发生了:因为JSX是原始数据的纯函数,它返回&#34; HTML&#34; (不是真的),同样的方式,CSS-in-JS是纯函数或原始数据返回&#34; CSS&#34; (也不是真的)。从这一点来说,我认为它值得reading about JSX和also 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)
我已经使用SCSS
(SASS
)多年了,并且也已经在一些大型项目中使用Styled-Components
。
我俩都爱,Styled-Components
对我来说就像向前迈进了一步。
我发现在 JSX 文件本身中使用 CSS 更加容易(我反对这个想法已有很多年了)
< / li>能够轻松使用样式内的javascript变量
只能在某些情况下这样查看缺点,而不能查看 一定是全部。
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规则。 如果您进行复杂的渲染更改(例如动画),请不要进行此操作。使用绝对位置或固定位置来完成此操作。
无论采用哪种样式,您都应接受建议。但是,我认为前两个可以通过我描述的方式使用样式化组件来覆盖,即创建一个组件工具包并将所有样式保留在其组件中。然后使用该工具包构建您的应用。