9 月 13 日,2025 Inclusion・外滩大会「开源嘉年华」正在限量报名中! 了解详情
写点什么

Emotion 库维护者解释为什么 Spot 公司不再使用运行时 CSS-in-JS

  • 2022-11-12
    北京
  • 本文字数:1877 字

    阅读完需:约 6 分钟

Emotion库维护者解释为什么Spot公司不再使用运行时CSS-in-JS

Sam Magura是 Spot 的软件工程师,也是活跃的Emotion库维护者。最近,他详细解释了 Spot 公司为什么放弃运行时 CSS-in-JS 库 Emotion,而选择了Sass模块——运行时开销、负载开销和服务器端渲染问题导致了较差的用户体验。


在他的博文中,Magura 首先回顾了运行时 CSS-in-JS 的好处。


今天的 Web 应用程序通常实现为一组协作的组件。在使用运行时 CSS-in-JS 库时,开发人员定义组件的样式以及组件标记和逻辑。如果以不正确的方式修改或删除了组件样式,就很难修改或删除组件代码。这解决了大型应用程序中充斥着未被检测到的过时样式规则的问题。但这样的应用程序下载和执行都比较笨重,对用户体验有负面影响。


将 CSS 规则的作用域严格限定到相关的组件就很难会无意影响到其他组件的样式。如果没有组件作用域,CSS 的级联和专一性规则可能会导致不相关组件的样式定义发生渗透。


最后,使用完备的图灵语言,如 JavaScript,开发人员可以完全自由地表达组件样式和组件逻辑之间的关系。如果组件样式不是静态的,并且需要根据用户操作或应用程序环境中的变更进行动态更新时,这样就很方便了。


不过,Magura 根据他对 Spot 代码库的研究得出结论,CSS-in-JS 的坏处大于好处:


所以,这就是我们放弃 CSS-in-JS 的原因——运行时性能成本太高了。


CSS-in-JS 可能会因其运行时和负载开销而对用户体验产生负面的影响。


一方面,在渲染时动态计算和更新样式可能会导致渲染变慢。Magura 比较了 Spot 用运行时 CSS-in-JS 库 Emotion 实现的代码库组件的渲染时间与用 Sass 模块实现的代码库组件的渲染时间(在构建时编译为普通的 CSS 文件)。对比显示,使用 Emotion 库的渲染时间几乎翻倍(27.7 毫秒对 54 毫秒)。开发人员可以从这篇博文中查看实验数据、火焰图分析等等。


另一方面,将 CSS-in-JS 库添加到应用程序代码中会加大浏览器下载的代码包,可能会降低应用程序的启动速度。Emotion 大约 8 KB(最小化后),而style-components,一个流行的 CSS-in-JS 库,是 12 KB。


有趣的是,运行时 CSS-in-JS 库执行的动态插入 CSS 样式规则可能并不总是与生态系统的其他部分很好地配合。


关于 React 18,Sebastian Markage在 GitHub Issues 中向使用 React 并发渲染功能的开发人员提出了如下的警告


这是一个 CSS 库(动态生成新规则并将它们与<style>标签插入到文档中)的升级指南,特别是目前大多数专门为 React 设计的 CSS-in-JS 库,如 styled-components、styled-jsx、react-native-web。


注意:请务必阅读“When to Insert <style> on The Client”部分。如果你现在在“渲染期间”注入样式规则,会导致你的库在并发渲染时非常慢。


运行时 CSS-in-JS 也可能影响服务器端渲染优化。在一篇关于服务器端流的文章中,Misko Hevery(Qwik框架的作者)、Taylor Hunt和 Ryan Carato写道


例如,CSS-in-JS(如 Emotion)是一种非常流行的方法。但是,如果这种方法意味着在输出样式标签之前所有组件都需要完全渲染,就会中断流,因为框架被迫缓冲整个响应。


Magura 提到,Emotion 的 GitHub 项目中记录的相当多的问题都与服务器端渲染有关(例如 React 18 的流、规则插入顺序)。报告的问题可能会产生显著的意外复杂性(即与解决方案相关的复杂性,而不是源于问题本身)。它们还可能导致负面的开发者体验。


虽然 Magura 提醒读者,他的实验仅限于 Emotion 库和 Spot 的代码库,但他预计大部分推理可能同样适用于其他运行时 CSS-in-JS 库和其他代码库。


一年前,Tomas Pustelnik提供了另一个数据点,尽管表述的方式不同,但指向的问题是相似的。Pustelnik 在他的博文“真实世界的CSS与CSS-in-JS的性能比较”中总结道:


就是这样。如你所见,运行时 CSS-in-JS 可以对网页产生明显的影响,主要针对低端设备和网络连接较慢或流量价格较高的地区。因此,也许我们应该更好地考虑使用什么工具以及如何使用工具。好的开发者体验不应该以牺牲用户体验为代价。


我认为我们(开发人员)应该更多地考虑我们为项目所选择的工具可能带来哪些影响。如果下一次我开始一个新项目,我将不再使用运行时 CSS-in-JS。我要么使用普通的 CSS,要么使用一些构建时 CSS-in-JS 替代方案。


流行的构建时 CSS-in-JS 库包括LinariaAstroturfvanilla-extract。去年,Facebook 推出了自己的构建时 CSS-in-JS 库stylex,开发人员仍然可以使用CSS模块和相关的生态系统(PostCSS模块Sass模块)。


CSS-in-JS 指的是通过 JavaScript 生成 CSS 规则,而不是在外部 CSS 文件中定义样式。运行时 CSS-in-JS 库,如Emotionstyles-component,在运行时动态修改样式,例如将样式标签注入文档。零运行时 CSS-in-JS 是一种在构建时提取所有 CSS 的模式。


查看英文原文https://www.infoq.com/news/2022/10/prefer-build-time-css-js/

2022-11-12 10:005103

评论

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

架构师训练营学习总结——缓存与消息队列【第五周】

王海

极客大学架构师训练营

开发人员应当避免的代价高昂的职业错误

小隐乐乐

职业规划 职业素养 架构师

使用@AutoConfigureBefore调整配置顺序竟没生效?

YourBatman

Java Spring Boot @AutoConfigureBefore

架构师训练营 - 第五周 - 学习总结

韩挺

命题作业5-1 【C++实现版本】

天之彼方

c++

分布式缓存、消息系统和异步架构

架构5班杨娟Jessie

极客大学架构师训练营

架构师第5周总结

老姜

架构师训练营 - 第五周 - 作业

韩挺

Week 05 命题作业

卧石漾溪

极客大学架构师训练营

Week 5 作业

Shawn

首次揭秘!​春晚活动下快手实时链路保障实践

Apache Flink

Apache flink 架构 实时计算

第五周作业-一致性hash算法实现

吴建中

极客大学架构师训练营

你都如何回忆我,带着笑或是很沉默

小天同学

回忆 高考 青春

架构师训练营 Week 05 作业

Wancho

Spring 同名 Bean 加载策略

xiaoxi666

spring bean 同名 覆盖

springBoot集成rabbitmq并实现延时队列

生命在于折腾

RabbitMQ

区块链技术打通医疗应用场景

CECBC

行业资讯 生产 区块链技术 生活服务

week5-总结 技术选型

Geek_z9dmvw

Week 05- 作业一:一致性 hash 算法

dean

极客大学架构师训练营

Week 05- 作业二:学习总结

dean

极客大学架构师训练营

一致性Hash算法以及Java代码实现

架构5班杨娟Jessie

极客大学架构师训练营

week2作业

动手实现一致性hash算法

极客大学架构师训练营 分布式缓存 一致性哈希 一致性hash

【架构师训练营 - 作业 -5】一致性HASH算法实现

小动物

极客大学架构师训练营 作业 第五周

架构师训练营第5周作业

Bruce Xiong

不懂SpringApplication生命周期事件?那就等于不会Spring Boot嘛

YourBatman

Spring Boot SpringApplication

架构师训练营第五章总结

叮叮董董

用一致性Hash算法的实现负载均衡(Kotlin)

Acker飏

极客大学架构师训练营 一致性Hash算法

Week5 一致性hash算法

TiK

就餐卡系统设计

架构师训练营第五章作业

叮叮董董

Emotion库维护者解释为什么Spot公司不再使用运行时CSS-in-JS_大前端_Bruno Couriol_InfoQ精选文章