React CSS-In-JS 方案 : Linaria Vs Styled-Components

简介: 在开发一个 React 应用时,其中一个比较大的挑战就是为应用选择一个合适的样式处理方案。因为我们需要考虑到样式的可维护性,开发体验,以及样式对应用性能的影响等

hello 大家好,我是 superZidan,这篇文章想跟大家聊聊 React CSS-In-JS 方案 : Linaria Vs Styled-Components,如果大家遇到任何问题,欢迎联系我

在开发一个 React 应用时,其中一个比较大的挑战就是为应用选择一个合适的样式处理方案。因为我们需要考虑到样式的可维护性,开发体验,以及样式对应用性能的影响等。基于这些考虑,很多开发者会选择使用 CSS-in-JS 方案。CSS-in-JS 方案将 javascript 作用于编写应用样式上。这有利于提升样式的可维护性,在编写样式过程中使用更加模块化的方式,将「动态样式」引入 react 应用中。目前市面上有非常多的 CSS-in-JS 方案。本文选择了使用比较多的两个方案 LinariaStyled-components 进行比较

在本文中,我们将回顾这两个流行的 CSS-in-JS 方案: LinariaStyled-components 。我们将一起研究他们的功能,同时比较他们功能差异,性能以及生态。

CSS-in-JS 解决方案

CSS-in-JS 解决方案给我们提供了新的编写 CSS 的方式。这些方案使用以 javascript 为基础的 API 来创建和编写样式。主要的优点包括:

  • 动态样式:允许开发者编写动态 CSS
  • 元素作用域:可以把样式的范围固定在某些元素上
  • 消除无用代码:会自动除去应用中冗余的 CSS 代码
  • 支持自定义主题
  • 安装和设置简单
  • 支持 ES modules 和 作用域
  • 更加容易编写单元测试
  • 性能提升
  • 支持 SSR
  • 支持所有的 CSS 语法

Linaria

Linaria 是最流行的 CSS-in-JS 解决方案之一,GitHub 拥有 7.1k 个 star 和 260 个 fork。Linaria 是 「零运行时」方法,这意味着它将开发者写好的样式代码在构建时转换为一个单独的 .css 文件。这个行为跟很多的 CSS 预处理器相似,比如 SASS ,LESS

它提供了很多功能,包括:

  • 提供创建 CSS 类的 API 。”css” API 允许开发者创建所选择的样式,同时他也支持模版语法来满足当我们需要插入动态值。
import { css } from '@linaria/core';

const red = "red"
const header = css`
  text-transform: uppercase;
    color: ${red}
`;

<h1 className={header}>Hello world</h1>;

0.png

  • 它也提供可以创建元素的 API. “styled” API 允许开发者创建任何元素,比如: div,p,等等。当然,这个 API 也是支持模版语法来插入对应的变量值的
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;

1.png

  • 它通过 React 的 Props 或者常规变量来管理动态样式。在下面的代码中,我们通过 React 组件传递 props 和一些常规变量到另一个元素上
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;

2.png

其他的功能包括:

  • 通过 CSS source maps 可以很容易的找到样式变量是在哪里定义的
  • 可以在 JS 代码中开启 CSS Lint https://github.com/stylelint/stylelint
  • 通过 @linaria/atomic 可以支持原子样式

Styled-Components

Styled-Components 也是流行的 CSS-in-JS 解决方案之一。在 GitHub 上拥有 37.2 k 的 star 和 2.3 k 的 forks。Styled-components 让开发者能够通过编写真实的 CSS 代码来修改组件的样式。它在组件和样式之间创建了一个抽象层,从而消除了直接的映射。

提供的能力,包括:

  • 自动提取关键 CSS 和 代码分割:Styled-Components 监控组件,并且在组件渲染到页面的时候插入组件必要的样式代码。同时支持代码分割来加快组件加载的速度
  • 为样式生成唯一的类名,以防止样式的覆盖,拼写错误以及冗余
  • Styled-component 也提供通过 props 或者常规变量为元素注入动态值。“styled” API 允许开发者创建选择的元素,跟 Linaria 一样,Styled-component 也支持大致相同的模版语法
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;

3.png

  • 样式扩展:Styled-Components 允许在已有的样式上通过 styled 进行扩展
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;

3-1.png

4.png

其他的功能,包括:

  • 维护成本低
  • 更简便的删除不必要的 CSS
  • 支持 SSR
  • 支持主题定制

对比 Linaria 和 Styled-Components

开发者在很长一段时间都在选择最适合自己项目的样式解决方案,而 Linaria 和 Styled-Components 无疑是当中的佼佼者。接下来我们将从:「功能」,「性能」以及 「生态」来对这两个方案进行比较

功能

  • Linaria 是「零运行时」方案,这意味着样式文件会在构建时被单独抽取成 CSS 文件;Styled-Components 则是在构建时通过 javascript 将 CSS 注入,不会生成额外的 CSS 文件
  • 都拥有相似的 CSS 语法(类似 Sass 的风格)
  • 在 React 应用中都可以基于 Prop 实现变量注入(原理是使用 CSS 变量)
  • 都可以通过 CSS source maps 很快找到 CSS 变量定义的位置
  • 都可以通过 stylelint 的方案进行代码检查
  • 都使用 Javascript 来组织代码逻辑,无需使用 CSS 预处理器
  • 都可以平替 Sass 或者 PostCSS 方案

通过上述的的功能描述,我们发现 Linaria 和 Styled-Components 的 API 都比较相似,所以开发者很容易就可以从其中一个方案迁移到另一个方案

基于请求的性能对比

  • 在生产环境中, Linaria 会产生额外的 .css 文件,这将会引起 CSS 文件体积变大,文件数量变多,导致请求数量变多的问题
  • 对于 Styled-Components 来说,相同情况下,CSS 文件体积和数量无疑是更少的,但是会增加 JS bundle 的体积大小

许多争论在于认为 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 的使用。然后又对比两者之间的功能,性能特点以及生态系统。

本文的代码地址:

参考资料

目录
相关文章
|
19天前
|
JavaScript 前端开发 测试技术
在 golang 中执行 javascript 代码的方案详解
本文介绍了在 Golang 中执行 JavaScript 代码的四种方法:使用 `otto` 和 `goja` 嵌入式 JavaScript 引擎、通过 `os/exec` 调用 Node.js 外部进程以及使用 WebView 嵌入浏览器。每种方法都有其适用场景,如嵌入简单脚本、运行复杂 Node.js 脚本或在桌面应用中显示 Web 内容。
52 15
在 golang 中执行 javascript 代码的方案详解
|
12天前
|
存储 网络架构
Next.js 实战 (四):i18n 国际化的最优方案实践
这篇文章介绍了Next.js国际化方案,作者对比了网上常见的方案并提出了自己的需求:不破坏应用程序的目录结构和路由。文章推荐使用next-intl库来实现国际化,并提供了详细的安装步骤和代码示例。作者实现了国际化切换时不改变路由,并把当前语言的key存储到浏览器cookie中,使得刷新浏览器后语言不会失效。最后,文章总结了这种国际化方案的优势,并提供Github仓库链接供读者参考。
|
1月前
|
前端开发 JavaScript 测试技术
React 中集成 Chart.js 图表库
本文介绍了如何在 React 项目中集成 Chart.js 创建动态图表,涵盖基础概念、安装步骤、代码示例及常见问题解决方法,帮助开发者轻松实现数据可视化。
40 11
|
1月前
|
前端开发
create-react-app 如何使用 less/sass 和 react-css-modules?
本文详细介绍了在 create-react-app 项目中如何使用 less/sass 和 react-css-modules 来管理和应用样式。首先,通过安装相应依赖并配置 webpack 支持 less/sass;接着,介绍如何使用这些预处理器编写样式;最后,讲解了如何配置和使用 react-css-modules 实现样式的模块化管理,以及如何结合使用 less/sass 和 react-css-modules 提高开发效率和代码质量。
32 3
|
2月前
|
移动开发 前端开发 JavaScript
React DnD:实现拖拽功能的终极方案?
本文首发于微信公众号“前端徐徐”,介绍了一个强大的 React 拖拽库——React DnD。React DnD 帮助开发者轻松创建复杂的拖拽界面,适用于 Trello 风格的应用、列表重排序、可拖拽的 UI 组件等场景。文章详细介绍了 React DnD 的基本信息、主要特点、使用场景及快速上手指南。
156 3
React DnD:实现拖拽功能的终极方案?
|
1月前
|
监控 前端开发 JavaScript
React 静态网站生成工具 Next.js 入门指南
【10月更文挑战第20天】Next.js 是一个基于 React 的服务器端渲染框架,由 Vercel 开发。本文从基础概念出发,逐步探讨 Next.js 的常见问题、易错点及解决方法,并通过具体代码示例进行说明,帮助开发者快速构建高性能的 Web 应用。
87 10
|
1月前
|
资源调度 前端开发 数据可视化
构建高效的数据可视化仪表板:D3.js与React的融合之道
【10月更文挑战第25天】在数据驱动的时代,将复杂的数据集转换为直观、互动式的可视化表示已成为一项至关重要的技能。本文深入探讨了如何结合D3.js的强大可视化功能和React框架的响应式特性来构建高效、动态的数据可视化仪表板。文章首先介绍了D3.js和React的基础知识,然后通过一个实际的项目案例,详细阐述了如何将两者结合使用,并提供了实用的代码示例。无论你是数据科学家、前端开发者还是可视化爱好者,这篇文章都将为你提供宝贵的洞见和实用技能。
63 5
|
1月前
|
JavaScript 前端开发 开发者
JavaScript框架React vs. Vue:一场性能与易用性的较量
JavaScript框架React vs. Vue:一场性能与易用性的较量
34 0
|
3月前
|
自然语言处理 JavaScript 前端开发
一文梳理JavaScript中常见的七大继承方案
该文章系统地概述了JavaScript中七种常见的继承模式,包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合继承等,并探讨了每种模式的实现方式及其优缺点。
一文梳理JavaScript中常见的七大继承方案
|
2月前
|
前端开发 JavaScript
React Tailwind CSS
10月更文挑战第12天
20 1