解码数字化之路,56 个深度转型案例正式上线,立即查看>> 了解详情
写点什么

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

评论

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

头脑风暴:打家劫舍2

HelloWorld杰少

算法 LeetCode 动态规划 8月月更

openEuler 资源利用率提升之道02:典型应用下的效果

openEuler

开源 数据 cpu 操作系统 openEuler

超人飞来!Flutter 实现满屏的力量感动画!

岛上码农

flutter ios 移动端开发 安卓开发 8月月更

兼容并蓄广纳百川,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang复合容器类型的声明和使用EP04

刘悦的技术博客

golang go doc 教程 教程分享 golang 面试

如何让您的wiki内容更高级?

Geek_da0866

Go-Excelize API源码阅读(四)——Save()

Regan Yue

Go 开源 源码刨析 8月日更 8月月更

借问变量何处存,牧童笑称用指针,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang类型指针(Pointer)的使用EP05

刘悦的技术博客

入门 教程 Go web 教程分享 入门介绍

培训预告 | 企业应用现代化实用教程——DevOps方法论及最佳实践篇 8月11日上线

York

DevOps 云原生 团队建设 降本增效 应用现代化

MySQL权限管理

武师叔

8月月更

经验分享|低成本快节奏搭建企业知识管理系统的方法

Baklib

舔狗至高境界,学会这个技巧让你从舔狗升华到海王【Python趣味爬虫】

Geek_ac6fb9

后端

SRv6故障管理

穿过生命散发芬芳

8月月更 SRv6

运筹帷幄决胜千里,Python3.10原生协程asyncio工业级真实协程异步消费任务调度实践

刘悦的技术博客

Python 协程 Async Python3 协程原理

开源一夏 | RuntimeException 子类

六月的雨在InfoQ

开源 8月月更

【高并发】别闹了,要实现亿级流量下的分布式限流,这些算法你必须掌握!!

冰河

并发编程 多线程 高并发 协程 异步编程

Linux下Docker安装部署以及云原生的理解

Geek_acae888666

云原生 Docker 镜像

什么是Shell?从小白到入门你只差一个它

Albert Edison

Linux centos 运维 shell脚本编程 8月月更

企业进行知识共享的好处有哪些?

Geek_da0866

Unity Metaverse(四)、接入环信IM SDK 实现用户登录注册

CoderZ

Unity 登录验证 环信im 8月月更

分门别类输入输出,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang基本数据类型和输入输出EP03

刘悦的技术博客

golang 编程 教程 教程分享 golang 面试

如何用精益敏捷组合管理,提升研发效能?|ONES 研发管理大师课

万事ONES

深度解读 | 关于SBOM最基础元素,你需要知道的(Part I)

安势信息

开源 漏洞 SCA SBOM 最基础元素

开源一夏 | 基于 Serverless一键体验FastAPI

六月的雨在InfoQ

阿里云 开源 Serverless FC 8月月更

直播 | 服务餐饮商户年交易额超 7000 亿,哗啦啦如何用 StarRocks 搞定实时报表

StarRocks

数据库

文档管理系统对于企业来说有哪些作用?

Baklib

Spring Cloud Stream 消息发送

急需上岸的小谢

8月月更

Netty入门 -- 什么是Netty?

Bug终结者

Netty 8月月更

阿里云数据库PolarDB开源人才培养计划发布!万元好礼等你来拿!

阿里云数据库开源

数据库 阿里云 开源 认证 polarDB

LeaRun模型驱动开发框架 重塑企业生产力

力软低代码开发平台

低代码实现探索(四十七)低的不止前端,还有后端

零道云-混合式低代码平台

开源一夏 | jQuery对于链和捕获的实战研究

恒山其若陋兮

开源 8月月更

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