写点什么

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:003389

评论

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

YashanDB复杂查询性能提升的核心方法解析

数据库砖家

YashanDB高并发处理能力的设计思路

数据库砖家

深度解析:超融合环境下的数据管理与存储关键技术

智驱前线

YashanDB的时间序列数据管理及查询优化

数据库砖家

YashanDB动态分区策略及性能优势解析

数据库砖家

用了一个月 ToDesk:聊聊这款远程控制工具的真实体验

Toekn_w

YashanDB的实时数据处理能力分析

数据库砖家

YashanDB的异构数据集成技术详解与实践

数据库砖家

YashanDB对接主流中间件实现高效数据交互

数据库砖家

YashanDB分布式系统中的负载均衡设计详解

数据库砖家

YashanDB高并发处理能力及性能优化全攻略

数据库砖家

YashanDB高性能索引结构及优化策略探讨

数据库砖家

团队架构的月之暗面

俞凡

团队管理

YashanDB的可扩展性分析及应用效果

数据库砖家

YashanDB的可视化管理工具功能分析

数据库砖家

YashanDB多节点协作机制及其优势分析

数据库砖家

YashanDB分布式事务处理的应用场景与挑战

数据库砖家

YashanDB多语言支持及跨平台应用能力分析

数据库砖家

YashanDB多租户架构设计及其企业价值

数据库砖家

YashanDB分布式存储架构的设计精髓解读

数据库砖家

YashanDB高可用架构设计关键要素详解

数据库砖家

链游钱包开发冷钱包开发热钱包开发web3開發多链钱包NFT 钱包跨链钱包开发

西安链酷科技

YashanDB的实用功能:跨平台数据访问

数据库砖家

YashanDB的最新特性解析与使用建议

数据库砖家

YashanDB对现代企业数字化转型的关键推动作用

数据库砖家

YashanDB高效数据管理的5大实用技巧

数据库砖家

YashanDB的性能优化:实用策略与建议

数据库砖家

YashanDB对企业数据备份与灾难恢复的支持

数据库砖家

YashanDB多维数据模型设计及应用场景解析

数据库砖家

YashanDB的缓存机制深入剖析及实用优化技巧

数据库砖家

YashanDB对企业数据治理的支持机制解析

数据库砖家

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