样式组件很慢。但是,我们可以通过使用一些本机CSS功能来提高其性能吗?我决定测试它。
问题
样式组件的问题是它们基于运行时值重新计算样式。每次渲染组件时,都需要构建样式表并将其插入文档中。这不是小应用程序中的问题,而是较大的应用程序,它会影响性能。
您要避免的是动态组件(取决于主题或道具的组件)。
在将动态组件插入DOM之前,它需要解析模板生成CSS的预处理样式,将其注入DOM 。另一方面,静态组件可以跳过其中的一些步骤,因此更快。
探索替代方案
考虑到,我开始探索如何将动态组件重写为静态组件。
这是动态样式组件的经典示例。
const Box = styled.div`
padding: ${props => props.padding};
`
<Box padding="1rem">I'm a box</Box>
在CSS变量的帮助下,可以轻松地将其作为静态组件重写。
const Box = styled.div`
font-size: var(--padding);
`
<Box style={{--padding: '1rem'}}>I'm a box</Box>
,但通常,在较大的应用程序中,我们不直接使用特定值,而是从设计系统中设计令牌。
这是一个类似的例子,但是这次带有三个选项的填充。
const Box = styled.div<{padding: 'small' | 'medium' | 'large'}>`
padding: ${props => {
switch (props.color) {
case "small":
return "1rem";
case "medium":
return "2rem";
case "large":
return "3rem";
}
}};
`
<Box padding="medium">I'm a box</Box>
在这种情况下,我们可以真正使用CSS变量。但是我们可以使用数据属性。
const Box = styled.div<{'data-padding': 'small' | 'medium' | 'large'}>`
&[data-padding="small"] {
padding: 1rem;
}
&[data-padding="medium"] {
padding: 2rem;
}
&[data-padding="large"] {
padding: 3rem;
}
`
<Box data-padding="medium">I'm a box</Box>
这看起来并不糟糕,而且更容易阅读。
这种方法的唯一缺点是,它实际上将data-padding
属性渲染到DOM中。写信给DOM可能也会影响性能。
表现
我决定对其进行测试。
在此simple demo中,我使用3种不同的方法构建了一个带有1000个项目的表。第一个是使用动态样式的组件,第二个是使用静态样式的组件,第三个是使用普通的旧CSS类名称 。
事实证明,使用data-attributes
的确比在样式组件上使用动态道具要快一些。毫不奇怪,最快的是使用CSS类名称。
使用本机CSS功能确实可以提高样式组件的性能。它使样式也更具可读性。与其在JS文件中的CSS声明内部编写JS函数中的CSS,您只能编写每个人都了解的CSS。
但是在JS中使用CSS仍然存在争议。它在伤害用户体验的同时改善了DX。
只要JS中的CSS不能同时改善UX&DX,就最好坚持使用普通的旧CS和一些良好的CSS方法。