我们为什么要放弃CSS-in-JS

246 阅读2分钟

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;
`;

Emotion

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 兼容,这是必要的。