GitHub 从 CSS-in-JS 迁移后为什么选择更多静态 CSS
GitHub 这次并不是简单地“抛弃 CSS-in-JS,改回写 CSS 文件”,而是在回答一个更具体的性能问题:当设计系统和页面组件持续增长,样式生成、收集与更新仍然留在运行时,浏览器初始化和服务端渲染都会反复支付成本。GitHub 最终选择让更多样式在构建阶段变成 CSS Modules,再随页面 HTML 一起交付。
GitHub Engineering Blog 在 2026 年 9 月 25 日公布了完整复盘,原文地址为 https://github.blog/engineering/architecture-optimization/improving-site-performance-by-shipping-more-css/。公开结果很醒目:页面服务端渲染时间减少 55%,组件初始化时间减少 25%。但真正值得借鉴的不是这两个数字本身,而是 GitHub 如何建立基线、控制迁移范围并逐步删除旧运行时依赖。
基线:CSS-in-JS 为什么在 GitHub 规模下变贵
CSS-in-JS 的优势并没有突然消失。组件与样式共置、动态属性、主题能力和局部封装,曾经都让 Primer 设计系统更容易演进。问题出现在规模扩大之后:到 2023 年,GitHub 的组件数量持续增加,原本分散在单个组件里的少量运行时开销,开始在整页渲染路径中累积。
GitHub 归纳了三类直接成本。第一,客户端需要初始化样式运行时,首屏可交互前多做了一段 JavaScript 工作;第二,SSR 期间服务器要收集组件产生的样式,服务端响应时间被拉长;第三,组件越多,样式更新和依赖传播越难控制。换句话说,样式不只是“最后显示成什么颜色”,它已经参与了页面启动和服务端渲染的关键路径。
这也是判断 CSS 方案时常被忽略的地方:源代码看起来简洁,并不代表生产路径成本低。应该分别测量构建期、SSR、客户端下载、初始化和交互更新,而不是只比较语法或单个组件的开发体验。
假设:把样式工作从运行时移到构建产物
GitHub 选择 CSS Modules,是因为它保留了组件附近的样式文件和局部类名,同时不要求浏览器或服务器运行样式生成逻辑。构建系统可以提前处理类名和依赖,生成普通样式表;页面返回 HTML 时,CSS 作为静态资源一起进入交付链路。

这项改动的本质是改变“工作发生在哪里”。CSS-in-JS 把一部分工作推迟到请求处理或浏览器初始化;CSS Modules 则把更多工作前移到构建阶段。前者适合确实需要运行时动态计算的样式,后者更适合大量可提前确定的组件样式。GitHub 并不是证明静态 CSS 在所有项目里都更优,而是证明自己的主要样式负载没有必要继续占用运行时预算。
迁移设计:先改设计系统,再用护栏扩大范围
大站点不能一次替换全部样式。GitHub 先从 Primer 组件入手,把每个组件的样式翻译成 CSS Modules,并保留旧实现和新实现之间的功能开关。这样同一个组件可以在受控范围内切换,出现问题时也能快速回退,而不是等到全站切换后才发现视觉偏差。
迁移同时配套视觉回归快照。CSS 重构最危险的地方往往不是编译失败,而是间距、层叠顺序、状态样式或主题组合发生细小漂移。自动截图对比可以把这些差异提前暴露,再配合从团队、员工到全部用户的分层发布,把风险限制在可观察范围内。

到 2024 年 12 月,所有 Primer 组件已经完成迁移。这个顺序很关键:先改共享设计系统,可以让后续页面迁移复用同一套基础能力;如果各业务页面各自发明迁移方式,旧依赖会换一种形式继续存在,最终很难真正删除运行时库。
结果:55% 和 25% 分别说明什么
GitHub 报告的两个核心结果分别指向服务端与客户端:页面 SSR 时间减少 55%,组件初始化时间减少 25%。前者说明服务器不再为同一批组件反复收集和组装运行时样式,后者说明客户端启动时减少了样式系统初始化工作。
阅读这类数据时要注意测量范围。它们是 GitHub 在自身架构、组件规模和迁移完成度下得到的结果,不应直接套成其他团队的收益预测。更有价值的做法是复用它的测量框架:
- 分别记录 SSR 总耗时与样式收集耗时,不只看平均响应时间;
- 记录组件初始化和 hydration 阶段的主线程占用;
- 比较迁移前后的 JavaScript 依赖、CSS 体积与缓存命中;
- 在相同页面、相同流量分层和相同设备条件下做对照。
静态 CSS 也可能带来新的成本,例如未使用样式、样式表体积增长、加载顺序和缓存失效。如果只看到 JavaScript 下降,却没有观察 CSS 下载和渲染阻塞,就可能把成本从一个位置挪到另一个位置。因此,GitHub 的结论应该理解为“用整体页面指标验证架构选择”,而不是“CSS 文件越多越快”。
清理 sx:真正困难的是长尾用法
设计系统组件迁移完成后,页面里的 sx 属性仍然形成长尾。GitHub 先组织 8 名工程师轮转,在 6 个月内迁移 6419 个属性。不同页面的 SSR 改善并不一致,公开范围从 1% 到 22%,这正说明长尾样式的收益与页面结构、组件密度和原有运行时调用有关。
到 2026 年 4 月,团队又使用 2 名工程师配合 Copilot coding agents,在 3 周内把剩余 895 个 sx 属性降到 0。自动化适合处理可机械转换的重复模式,但功能开关、视觉回归和人工审查仍然负责判断“结果是否保持一致”。这比把代码生成工具当作独立迁移策略更稳妥。
主题解耦:七套主题不能再绑在运行时里
github.com 支持七套主题,而且每套主题还有高对比度变体。只替换组件写法并不足以删除 CSS-in-JS 依赖,因为主题值和旧运行时仍可能互相绑定。GitHub 因此把主题能力从样式运行时中解耦,再通过功能开关逐步移除依赖。
截至 2026 年 6 月,github.com 已经 100% 使用 CSS Modules,并移除了 sx、styled-components 和 styled-system。这一步才意味着迁移完成:不是“新代码默认不用”,而是旧入口、旧依赖和旧主题耦合都退出了生产路径。
其他团队可以复用的判断框架
是否迁移,不应从技术偏好出发,而应从运行时成本是否进入关键路径出发。可以先回答以下问题:
- 样式运行时在 SSR、hydration 和首次交互中分别占多少时间?
- 有多少样式真的需要根据运行时数据动态计算?
- 共享设计系统能否先提供双实现和稳定的类名边界?
- 是否具备视觉回归、功能开关、分层发布和快速回退能力?
- 主题、令牌和高对比度模式能否脱离原运行时独立工作?
- 迁移完成后,能否彻底删除旧 API 与旧依赖?
如果样式规模不大、没有 SSR,或者大量样式确实依赖运行时状态,迁移收益可能有限。相反,如果设计系统覆盖广、SSR 压力明显、组件初始化占用可观,而且大部分样式都能静态确定,GitHub 的路径就很有参考价值:先量化成本,再从共享组件开始,用双轨和视觉回归控制风险,最后处理长尾并删除依赖。
常见问题
GitHub 是因为 CSS-in-JS 本身有问题才迁移吗?
不是。GitHub 强调的是自身规模下的客户端初始化、SSR 样式收集和更新成本。CSS-in-JS 仍可能适合需要高度动态样式或规模较小的应用,关键是运行时收益是否抵得过成本。
为什么选择 CSS Modules,而不是全局 CSS?
CSS Modules 保留了样式与组件共置、局部类名和构建期处理,同时把运行时样式生成移出关键路径。它更接近 GitHub 原有组件化开发方式,也降低了迁移心智跨度。
迁移时最重要的安全网是什么?
不是某个转换脚本,而是可回退的功能开关、视觉回归快照和分层发布。三者让代码转换、视觉一致性和生产影响可以分别观察,避免把所有风险押在一次全量上线。
怎样判断迁移是否真正结束?
新组件使用新方案只是开始。只有旧属性入口归零、主题系统解耦、运行时依赖被删除,并且性能与视觉指标在全量流量下稳定,才算完成。
Go http.Protocols 怎么限定客户端使用的 HTTP 版本
- 上一篇
- Go http.Protocols 怎么限定客户端使用的 HTTP 版本
- 下一篇
- tuozi工具箱的产品站和下载域名有什么区别?入口辨识与使用边界说明
-
- 科技周边 · 业界新闻 | 3小时前 | 人工智能 · openai · OpenAI Codex DevDay 2026 Agents API
- OpenAI DevDay 2026 公布了哪些开发者活动信息
- 343浏览 收藏
-
- 科技周边 · 业界新闻 | 5小时前 | 云原生 · kubernetes · 业界新闻 · prometheus 多租户 Kubernetes GPU 指标 指标隔离
- 多租户 Kubernetes 的 GPU 指标为什么需要自助与隔离
- 376浏览 收藏
-
- 科技周边 · 业界新闻 | 7小时前 | 云原生 · kubernetes · 业界新闻 · Kubernetes 灾难恢复 恢复验证 有状态应用
- Kubernetes 可复现故障场景为何强调恢复验证
- 377浏览 收藏
-
- 科技周边 · 业界新闻 | 10小时前 | kubernetes · 业界新闻 · 云原生 Kubernetes GPU调度 分布式AI训练
- 分布式 AI 训练为什么正在改变云原生平台设计
- 200浏览 收藏
-
- 科技周边 · 业界新闻 | 12小时前 | kubernetes · 业界新闻 · Gateway API 云原生网络 HTTPRoute Cilium 1.20 ExternalAuth ext_authz
- Cilium 1.20 加入 Gateway API ExternalAuth 有何意义
- 118浏览 收藏
-
- 科技周边 · 业界新闻 | 15小时前 | 云原生 · 业界新闻 · 生产运维 · 可观测性 OpenTelemetry 平台工程 OTel Collector 指标平台
- 大规模指标平台迁移到 OpenTelemetry 反映了哪些趋势
- 419浏览 收藏
-
- 科技周边 · 业界新闻 | 17小时前 | 云原生 · 业界新闻 · 安全治理 · 云原生 Kubernetes AI Agent 工具权限 CNCF Agent Harness 身份治理
- CNCF 社区为什么开始讨论云原生 Agent Harness
- 279浏览 收藏
-
- 科技周边 · 业界新闻 | 19小时前 |
- OpenSSF Security Slam 2026 秋季活动关注什么
- 487浏览 收藏
-
- 科技周边 · 业界新闻 | 1天前 |
- GitHub 新 Dashboard 成为默认首页有哪些变化
- 492浏览 收藏
-
- 科技周边 · 业界新闻 | 1天前 |
- GitHub App 无状态安装令牌完成上线意味着什么
- 221浏览 收藏
-
- 科技周边 · 业界新闻 | 1天前 |
- 开源项目毕业与企业生产采用之间的评估清单
- 471浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 333次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 391次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 386次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 353次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 176次使用
-
- go zero微服务实战性能优化极致秒杀
- 2022-12-27 207浏览
-
- Go pprof 排查慢接口:别只会看火焰图,先把问题问对
- 2026-06-01 101浏览
-
- Go JSON v2 实战:别急着替换 encoding/json,先搞懂这些变化
- 2026-06-01 437浏览
-
- Go 1.25 容器感知 GOMAXPROCS:K8s 里别再让 CPU limit 偷偷拖垮 P99
- 2026-06-01 473浏览
-
- Go map 新实现实战:Swiss Tables 变快了,但别急着改业务代码
- 2026-06-01 218浏览

