CSS-in-JS vs 传统CSS:一个天通苑奶爸的深夜技术抉择

一键启动人生
2025-12-16 00:54
阅读 330

上周五晚上11点27分,我终于把两个娃——三岁半的乐乐和一岁半的米粒——哄睡了。老婆在客厅刷《甄嬛传》重播(她说这剧能解压),我轻手轻脚溜进次卧,打开那台服役四年的MacBook Pro,屏幕幽光照亮了我布满黑眼圈的脸。

那天白天刚被主管拉去开需求评审会,新项目要用React重构老后台系统。散会后他拍拍我肩膀:“老张,样式这块你来定方案吧,别再用那些老旧的BEM命名了。” 我点头应下,心里却咯噔一下——CSS到底该怎么写?用CSS Modules?还是试试最近很火的Styled Components?

坐标北京天通苑,房租3500一个月(合租),月薪18k,房贷车贷加奶粉钱每月雷打不动支出1.6w。作为两个娃的奶爸,我比谁都清楚:一次错误的技术选型,可能让我加班到凌晨三点,而凌晨三点的我,第二天根本扛不住乐乐早上六点的“爸爸起床!”攻击


从一场失败的面试说起

其实我对“怎么写CSS”这个问题的焦虑,早在去年十月就埋下了种子。

那会儿我在看新机会,面了一家做跨境电商的A轮融资公司。技术二面时,面试官是个戴黑框眼镜、说话慢悠悠的前端TL。聊完React原理和性能优化后,他突然问:

“你们项目现在用什么样式方案?为什么选它?有没有考虑过CSS-in-JS?”

我当时支支吾吾说用了SCSS + BEM,因为“团队熟悉”、“好维护”。他点点头没多问,但后来HR委婉告诉我:“技术深度还可以,但在工程化和现代前端实践上略显保守。”

回家路上,地铁13号线挤得像沙丁鱼罐头,我盯着手机里那封拒信,心里不是滋味。月薪从15k涨到22k的机会,可能就卡在了这个“样式方案”的问题上

当晚哄睡孩子后,我翻出掘金、知乎、GitHub Trending,一口气看了十几篇关于CSS-in-JS的文章。越看越懵:Emotion、Styled Components、Linaria、Vanilla Extract……这些工具名字听着就高级,但真的适合我们这种中小团队吗?

更关键的是——它们会不会让我本就不多的睡眠时间再少一小时?


真实项目中的血泪教训

今年3月,我们接了个政府数据可视化项目,工期紧、UI复杂。我一咬牙,决定试水Styled Components。

第一天还挺兴奋:“看!动态主题切换一行代码搞定!”
第三天就开始骂娘:“为什么热更新这么慢?改个颜色要等8秒?!”
第七天彻底崩溃:一个简单的hover效果,因为props嵌套太深,生成了一串长得离谱的类名,DevTools里根本没法调试

最要命的是,项目中期来了个新人小李——985科班,但只用过传统CSS。他对着满屏的styled.div一脸懵:“张哥,这个按钮的样式在哪改?全局变量又在哪?”

我花了整整一个下午给他讲ThemeProvider、css prop、Server-Side Rendering注意事项……那一刻我突然意识到:技术选型不只是“哪个更先进”,而是“团队能不能高效协作”

后来我们紧急回滚到CSS Modules + PostCSS,虽然少了些酷炫功能,但至少小李第二天就能独立开发页面了。上线那天,客户夸界面清爽,没人知道背后我们为样式方案吵过三次会。


奶爸的深夜实验室:亲自下场对比

既然实战踩过坑,不如自己动手测一测。于是过去两个月,每个娃睡后的23:30-1:30,成了我的“CSS方案压力测试时间”

我建了三个几乎一样的React应用(用Vite搭的,别卷Webpack了):

  1. 传统派:CSS Modules + SCSS + BEM命名
  2. 中间派:CSS Modules + PostCSS(支持嵌套、变量)
  3. 激进派:Emotion(社区目前最稳的CSS-in-JS方案)

测试维度 & 结果(真实数据!)

维度 传统CSS Emotion (CSS-in-JS)
首屏加载 23KB CSS文件 JS包增大42KB(含运行时)
热更新速度 平均1.2s 平均3.8s(开发模式)
主题切换 需要CSS变量+JS切换class 直接传theme props,秒切
组件隔离性 靠命名规范,偶尔污染 天然作用域隔离,零冲突
新人上手成本 1天(只要会CSS) 2-3天(需理解JSX+样式混合逻辑)
服务端渲染 静态文件直接引用 需额外配置extractCritical

最关键的发现:在我们的实际业务中(中后台管理系统,80%是表单/表格),传统CSS的开发效率反而更高。因为:

  • 设计稿基本固定,很少需要“根据props动态算样式”
  • 全局统一的按钮、输入框样式,用CSS变量维护比在每个组件里import theme更直观
  • 调试时直接右键“检查元素”就能改样式,不用翻半天JSX找styled定义

但!如果你在做高度动态的营销页、或者需要频繁换肤的C端产品,CSS-in-JS的优势就碾压了。比如我们另一个H5活动页项目,用Emotion配合Framer Motion做交互动效,简直丝滑到飞起。


工具链的隐藏成本:别只看API多优雅

很多教程吹CSS-in-JS时,只展示这行代码有多美:

const Button = styled.button`
  background: ${props => props.primary ? 'palevioletred' : 'white'};
  color: ${props => props.primary ? 'white' : 'palevioletred'};
`;

但没人告诉你:

  1. 打包体积增加:Emotion运行时约8KB(gzip后),对性能敏感的项目可能是负担
  2. Source Map错位:报错时定位不到原始样式代码,调试体验降级
  3. 缓存失效:JS更新会导致整个样式缓存失效,而传统CSS可单独缓存
  4. TypeScript支持:虽然现在有@emotion/react的TS类型,但写起来还是比纯CSS啰嗦

上周四凌晨1点,我就被一个诡异bug折磨了两小时:某个Table组件在SSR时样式错乱,CSR后才恢复正常。最后发现是Emotion的CacheProvider没配好。而同样的问题,在传统CSS里根本不会存在——静态资源就是静态资源。

作为奶爸程序员,我越来越怕“聪明但脆弱”的方案。孩子半夜发烧时,我可没心思研究为什么CSS-in-JS在Node环境渲染异常。


面试题背后的真相:面试官到底想听什么?

回到开头那场失败的面试。现在我明白了,面试官问“CSS方案选择”,根本不是要你背工具优缺点,而是考察你的工程思维

  • 你是否考虑团队规模和成员水平?
  • 你是否权衡过长期维护成本?
  • 你是否根据业务场景做决策?

所以现在如果再有人问我,我会这样答:

“我们目前主力项目用CSS Modules + PostCSS。原因有三:

  1. 团队5个前端,2个实习生,降低学习成本;
  2. 项目90%是管理后台,动态样式需求少;
  3. 性能指标要求FCP<1.2s,避免JS运行时开销。

但我们在新孵化的H5活动页中试水Emotion,因为需要大量动画和主题定制。技术没有银弹,只有‘当下最合适’的方案。

你看,重点不是工具本身,而是你的决策逻辑。这比背八股文有用多了。


给 fellow 奶爸程序员的建议

写到这里,窗外天通苑的早班车已经呼啸而过。再过两小时,乐乐又要爬起来喊“爸爸做 pancakes!”。

作为一个在生存线上挣扎的技术人,我想分享几点掏心窝子的话:

  1. 别被“新技术焦虑”绑架
    CSS-in-JS很酷,但如果你的业务用不到它的核心优势(动态样式、强隔离),何必自找麻烦?稳定交付比技术炫技重要一百倍——尤其是当你需要准时下班接娃放学的时候。

  2. 把“可维护性”放在第一位
    想想六个月后的自己:当需求变更时,你是希望看到清晰的.btn-primary,还是在JSX里翻三层props找颜色值?代码是写给人看的,其次才是机器

  3. 小步快跑,别all in
    如果真想尝试CSS-in-JS,先在一个非核心页面试点。就像我先拿H5活动页试水,而不是直接重构主系统。

  4. 和设计师对齐预期
    很多团队引入CSS-in-JS是因为设计师总改色值。但其实用CSS变量 + Design Token也能解决。工具服务于流程,别让流程迁就工具


最后:技术人的尊严不在工具链,而在解决问题

昨天老婆看我熬夜查文档,叹了口气说:“要不咱们回老家吧?你在这累死累活,图啥呢?”

我没回答。但今天写这篇文章时,我突然有了答案:

我图的不是用上最潮的框架,而是在有限的时间里,做出既稳定又高效的系统——这样我才能在周五晚上陪乐乐搭乐高,而不是在工位上改第17版hover效果

CSS-in-JS or not?这个问题没有标准答案。但作为两个娃的奶爸,我的答案很朴素:

选那个让你少加班、多陪娃的方案

毕竟,孩子的成长只有一次。而CSS,明天还能接着写。


后记:本文所有测试数据基于个人MacBook Pro 2019 (i5/16GB),React 18 + Vite 4环境。如果你也在天通苑租房、家里有俩神兽、还在纠结技术选型——欢迎留言聊聊。说不定哪天咱能在龙德广场的麦当劳,一边啃汉堡一边吐槽webpack配置呢 :)

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝