CSS-in-Js
原文链接:Why We're Breaking Up with CSS-in-JS
什么是CSS-in-Js
顾名思义,CSS-in-JS 允许直接在 JavaScript 或 TypeScript 代码中编写 CSS,从而为 React 组件设计样式:
// @emotion/react (css prop), with object styles
function ErrorMessage({ children }) {
return (
<div
css={{
color: 'red',
fontWeight: 'bold',
}}
>
{children}
</div>
);
}
// styled-components or @emotion/styled, with string styles
const ErrorMessage = styled.div`
color: red;
font-weight: bold;
`;
import { css } from '@emotion/css'
const color = 'white'
render(
<div
className={css`
padding: 32px;
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
&:hover {
color: ${color};
}
`}
>
Hover to change color.
</div>
)
The Good
1、局部范围样式
避免类名冲突导致样式被引用的更广泛
2、同位
如果只使用纯css,可能会将所有样式写入style/XXX.css中,随着项目规模越来越大,很快就难以分辩某个组件使用了那些样式。
3、可以使用js中的变量
The Neutral
1、是一项热门的新技术
对新技术的痴迷&新的框架比前生拥有的进步(React与jQuery之间的差距)
The Bad
1、增加运行时开销
在组件渲染时,CSS-in-Js库必须将样式序列化为可插入文档的纯css,会占用额外的CPU周期
2、增加js包的大小(increases bundle size)
Emotion 的 minzipped 大小为 7.9 kB,styled-components 的 minzipped 大小为 12.7 kB。因此,这两个库都不算大,但加在一起也不小。(作为对比,react + react-dom 为 44.5 kB)。
3、使React DevTools更加混乱(clutters the React DevTools)
The Ugly
1、频繁插入css会使浏览器做很多额外的工作
Runtime CSS-in-JS 库的工作原理是在组件渲染时插入新的样式规则,从根本上影响了性能(在渲染过程中,要对节点重新计算最新的css样式)
2、易出错
a、Emotion会同时加载多个实例,哪怕多个实例版本相同,也会出现问题。
b、组件库无法控制样式的插入顺序。
c、Emotion 的 SSR 支持在 React 17 和 React 18 之间的工作方式有所不同。为了与 React 18 的流 SSR 兼容,这是必要的。