写点什么

CSS-in-JS 性能成本缓解策略

  • 2020-02-01
  • 本文字数:2129 字

    阅读完需:约 7 分钟

CSS-in-JS性能成本缓解策略

作为一种将组件逻辑链接到其样式的方式,CSS-in-JS 在某些场景中变得流行起来。Aggelos Arvanitakis提醒开发人员,在某些情况下,不再能忽略 CSS-in-JS 的成本,并且提供了缓解策略。


Arvanitakis 在一篇文章中指出,尽管 CSS-in-JS 带来了好处,但是,它仍可能在某些应用程序中造成性能问题。Arvanitakis 把重点放在 React 和两个流行的 CSS-in-JS 库(styled-componentsemotion)上,他比较了相同代码的两个版本,其中只有一个版本使用了 CSS-in-JS 样式。无样式版本如下所示:


import React from 'react';const NormalDiv = props => <div {...props} />const App = () => {  const [randomValue, setRandomValue] = React.useState(0);  return (    <React.Fragment>      {new Array(50).fill(null).map((__, i) => (        <NormalDiv key={i}>Hello World</NormalDiv>      ))}      <button onClick={() => setRandomValue(Math.random())}>Force Rerender</button>    </React.Fragment>  );};
复制代码


样式版本如下所示:


import styled from '@emotion/styled';const StyledDiv = styled.div``;const App = () => {  const [randomValue, setRandomValue] = React.useState(0);  return (    <React.Fragment>      {new Array(50).fill(null).map((__, i) => (        <StyledDiv key={i}>Hello World</StyledDiv>      ))}      <button onClick={() => setRandomValue(Math.random())}>Force Rerender</button>    </React.Fragment>  );};
复制代码


样式化的 CSS-in-JS 的实现比无样式版本要多花 50%的时间在渲染上。尽管在很多情况下,很难察觉与 CSS-in-JS 相关的性能成本,但在其他情况下(如具有大型组件树),它的成本是很难忽略的。Arvantitakis 猜测使用某些库观察到的性能成本可能要归因于它们修改组件树(使用 Context 并添加 Context.Consumer 以读取样式值)以及动态地应用样式( style 标签包含动态注入的 CSS )。Arvanitakis 解释道:


一切都非常正常,直到我实现了一个 Table。我开始注意到渲染的速度很慢,尤其是行数超过 50 行之后。因此,我打开了 devtools 尝试研究它。

(……)

因此,总结来说,多个 Context 的使用者(这意味着 React 必须协调其他元素)以及动态样式附带的固有清理工作组合起来可能让应用程序的运行速度变慢了。


因此,Arvanitakis 得出了如下建议:


1.不要过度组合样式化的组件

2.首选“静态”组件

3.避免不必要的 React 重渲染

4.研究零运行时 CSS-in-JS 库是否适合我们的项目

(……)如果我们的应用程序不需要支持主题化,并且也没有使用大量复杂的 csspro,那么,零运行时 CSS-in-JS 库可能是个不错的选择。我们可以得到的好处是,整个包的大小将缩减大约 12KB,这是因为大多数 CSS-in-JS 库的大小在 10KB 到 15KB 之间,而零运行时库(如 linaria)的大小不到 1KB。


但是,Arvanitakis 警告大家,性能重构只应该发生在遇到或测量到性能问题之后。JSS CSS-in-JS 库的作者Oleg Isonen解释了 4 种常用的 CSS-in-JS 策略的权衡,并对比了 CSS-in-JS 库性能基准(截至 2019 年 3 月)。用选定的库进行基准测试得到的结果如下:



CSS-in-JS 可能仅限于类似 React 这样的基于组件的框架。其他流行的框架,如 Vue、Svelte 或Angular使用其他的托管策略,为开发人员提供类似的好处(像作用域 CSS 和摇树优化 CSS)。例如,Angular 的开发人员可以用类似 html 的模板文件、CSS 文件和 JavaScript 文件来定义其组件。然后,.js 的文件将引用其他两个文件:


// ./app.component.jsimport { Component } from '@angular/core';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css']})export  class AppComponent {  title = 'angular programming.';}
复制代码


后缀名为.js、.css 和.html 的文件应位于同一个目录中。另外,在模板和样式足够简短的情况下,Angular 开发人员可能更喜欢直接在 @Component 定义中以字符串的形式将模板和样式放到一起。这两种方法在语法上是不同的,但都提供了相同的作用域优势。


Vue鼓励采用单个.vue 文件,文件中包含 style 标记,其中含有 CSS 样式信息、类似 html 的模板和处理组件行为的 JavaScript 方法。类似的,Svelte读取.svelte 文件中的组件定义,.svelte 文件也包含同一文件中的样式、模板和逻辑信息。CSS-in-JS 还是 React 等框架使用托管(colocation)的另一种形式,这些框架使用 JavaScript 渲染函数而不是模板。


正如 Elm 的创建者Evan Czaplicki在推文中这样写道,组件就是对象。托管和封装样式以及模板属性,并将它们与处理组件逻辑的方法处理放到一起是对单一职责原则(Single Responsibility Principle)的一种反应,就像Robert C. Martin所解释的:


换句话说,单一职责原则就是:

把基于相同原因而改变的事物放在一起。把出于不同原因而改变的事物分开来。

如果仔细想想,那么我们就会明白,这只是定义内聚和耦合的另一种方式。我们希望提高因相同原因而改变的事物之间的内聚性,并且,我们希望降低因不同原因而改变的事物之间的耦合性。


Arvanitakis的全文包括其他个人资料,读者可以上网查看。


原文链接:


CSS-in-JS Performance Cost - Mitigating Strategies


2020-02-01 09:003426

评论

发布
暂无评论
发现更多内容

城市燃气安全再拉警钟,如何防患于未“燃”?

AIRIOT

物联网 天然气管理平台 燃气安全

算法题每日一练---第9天:第几个幸运数字

知心宝贝

算法 前端 后端 7月月更

7.依赖注入

MASA技术团队

后端

Rainbond插件扩展:基于Mysql-Exporter监控Mysql

北京好雨科技有限公司

云原生 #Kubernetes#

越来越成熟的Rust,都应用了哪些场景呢?

非凸科技

rust

喜讯!瑞云科技被授予“海上扬帆”5G融合应用专委会成员单位

3DCAT实时渲染

5G

阿里架构师花近三个月时间整理出来的Java独家面试题(Java岗)

程序员啊叶

Java 编程 程序员 架构 java面试

柏睿数据加入阿里云PolarDB开源数据库社区

阿里云数据库开源

开源数据库 polarDB PolarDB-X 阿里云数据库 PolarDB for PostgreSQL

免费的低代码开发平台有哪些?

优秀

低代码 低代码开发平台

从业务需求出发,开启IDC高效运维之路

鲸品堂

IDC

多租户软件开发架构

力软低代码开发平台

更新|3DCAT实时云渲染 v2.1.2版本全新发布

3DCAT实时渲染

3DCAT v2.1.3新版本发布,这三大功能更新你不容错过!

3DCAT实时渲染

云VR:虚拟现实专业化的下一步

3DCAT实时渲染

Cloud XR

今天去 OPPO 面试,被问麻了

程序员啊叶

Java 编程 程序员 架构 java面试

博云容器云、DevOps平台斩获可信云“技术最佳实践奖”

BoCloud博云

容器 DevOps 云原生 容器云

8 年产品经验,我总结了这些持续高效研发实践经验 · 研发篇

尔达Erda

产品 程序员 云原生 研发 效能

如何选择数字孪生可视化平台

3DCAT实时渲染

数字孪生

关于云XR介绍,以及5G时代云化XR的发展机遇

3DCAT实时渲染

XR 云XR

大型仿人机器人的技术难点和应用情况

优必选科技

机器人

Auditing相关注解

Damon

7月月更

Cloud XR面临的问题以及Cloud XR主要应用场景

3DCAT实时渲染

云流化和云桌面有什么关系

3DCAT实时渲染

手把手教你在 Vue3 中自定义指令

江南一点雨

为什么数字化未来取决于3D实时渲染

3DCAT实时渲染

实时云渲染

BATM面试Java岗:精选200+面试题及答案、6大重点规划和经验总结

程序员啊叶

Java 编程 程序员 架构 java面试

测试驱动开发(TDD)在线练功房 | 9月17日开课

ShineScrum

敏捷 测试 TDD 代码 测试驱动开发

Go语言系列:Go从哪里来,Go将去哪里?

小黑豆豆

后端 阅读 Go 语言 7月月更

实时云渲染有哪些优势

3DCAT实时渲染

实时云渲染

「行话」| 用DevOps高效交付游戏,是种什么体验?

极狐GitLab

git DevOps gitlab 敏捷开发 游戏开发

CSS-in-JS性能成本缓解策略_大前端_Bruno Couriol_InfoQ精选文章