在开发一个 React 应用时,其中一个比较大的挑战就是为应用选择一个合适的样式处理方案。因为我们需要考虑到样式的可维护性,开发体验,以及样式对应用性能的影响等。基于这些考虑,很多开发者会选择使用 CSS-in-JS 方案。CSS-in-JS 方案将 javascript 作用于编写应用样式上。这有利于提升样式的可维护性,在编写样式过程中使用更加模块化的方式,将「动态样式」引入 react 应用中。目前市面上有非常多的 CSS-in-JS 方案。本文选择了使用比较多的两个方案 Linaria 和 Styled-components 进行比较
在本文中,我们将回顾这两个流行的 CSS-in-JS 方案: Linaria 和 Styled-components 。我们将一起研究他们的功能,同时比较他们功能差异,性能以及生态。
CSS-in-JS 解决方案给我们提供了新的编写 CSS 的方式。这些方案使用以 javascript 为基础的 API 来创建和编写样式。主要的优点包括:
Linaria 是最流行的 CSS-in-JS 解决方案之一,GitHub 拥有 7.1k 个 star 和 260 个 fork。Linaria 是 「零运行时」方法,这意味着它将开发者写好的样式代码在构建时转换为一个单独的 .css 文件。这个行为跟很多的 CSS 预处理器相似,比如 SASS ,LESS
它提供了很多功能,包括:
import { css } from '@linaria/core';
const red = "red"
const header = css`
text-transform: uppercase;
color: ${red}
`;
<h1 className={header}>Hello world</h1>;
import { styled } from '@linaria/react'
const Container = styled.div`
font-size: 35px;
color: red;
border: 1px solid red;
&:hover {
border-color: blue;
}
h1 {
margin-bottom: 24px;
}
`;
const App = () => {
return <Container>
<h1>Hello World</h1>
</Container>
}
export default App;
import { styled } from '@linaria/react';
const Title = styled.h1`
font-family: inherit;
`;
const medium = 30
const Navbar = styled.nav`
font-size: ${medium}px;
color: ${props => props.color};
border: 1px solid red;
&:hover {
border-color: blue;
}
${Title} {
margin-bottom: 24px;
}
`;
const App = () => {
return <Navbar color="#999">
<Title>Hello world</Title>
</Navbar>
}
export default App;
其他的功能包括:
Styled-Components 也是流行的 CSS-in-JS 解决方案之一。在 GitHub 上拥有 37.2 k 的 star 和 2.3 k 的 forks。Styled-components 让开发者能够通过编写真实的 CSS 代码来修改组件的样式。它在组件和样式之间创建了一个抽象层,从而消除了直接的映射。
提供的能力,包括:
import styled from 'styled-components';
const Button = styled.button`
background: ${props => props.primary ? "palevioletred" : "white"};
color: ${props => props.primary ? "white" : "palevioletred"};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
const App = () => {
return <div>
<Button>Normal</Button>
<Button primary>Primary</Button>
</div>
}
export default App;
import styled from 'styled-components';
const Button = styled.button`
color: palevioletred;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
const TomatoButton = styled(Button)`
color: tomato;
border-color: tomato;
`;
const App = () => {
return <div>
<Button>Normal Button</Button>
<TomatoButton>Tomato Button</TomatoButton>
</div>
}
export default App;
其他的功能,包括:
开发者在很长一段时间都在选择最适合自己项目的样式解决方案,而 Linaria 和 Styled-Components 无疑是当中的佼佼者。接下来我们将从:「功能」,「性能」以及 「生态」来对这两个方案进行比较
通过上述的的功能描述,我们发现 Linaria 和 Styled-Components 的 API 都比较相似,所以开发者很容易就可以从其中一个方案迁移到另一个方案
许多争论在于认为 Linaria 产生的 css 文件对性能的影响是比较小的,相对于 Styled-Components ,Linaria 不会增加 JS bundle 体积是一种更好的取舍;而另一些则认为 Linaria 增加了 CSS 冗余代码的可能性。
我们可以在 这里 看到更多关于请求的性能对比
在加入多种页面加载标准之后发现,大部分的页面使用 Linaria 的加载性能要 好于 使用 Styled-Components。其中一个比较重要的原因就是,Linaria 导致的 CSS 资源体积与数量的增加对于页面加载的影响要小于 Styled-Components 导致的 JS bundle 体积的增加
我们可以从下面的资料中看到更多关于加载的对比
在这个方面的对比,主要是页面元素拖拽交互以及重新渲染;结果显示大部分的 Linaria 会有更少的脚本运行时间,更少的样式重绘重排
我们可以从下面的资料中看到更多关于渲染的对比
Styled-components 目前拥有 37.2K GitHub stars, 2.3K GitHub forks,超过 4百万的 NPM 包周下载量,可以说是 CSS-in-JS 最大的生态系统方案;而 Linaria 只有 7.1K GitHub stars, 260 GitHub fork 和 16000 的 NPM 包周下载量。这意味着 Styled-components 会有更大的社区以及讨论热度,更多的课程(学习成本低)以及更多的问题解答等等
本文我们先介绍了 Linaria 和 Styled-Component 的使用。然后又对比两者之间的功能,性能特点以及生态系统。
本文的代码地址:
翻译 — Oct 11, 2022
Made with ❤ and at Guangzhou.