CSS-in-JS首屏加载慢50–200ms,因样式注入必须等JS执行完,而传统CSS可并行下载、预解析、高效缓存,且运行时开销更高。

运行时注入样式必须等 JS 执行完才能开始
浏览器对 link rel="stylesheet" 有预加载器(preload scanner),JS 还没执行时,CSS 文件已在并行下载;而 CSS-in-JS 的 style.textContent = '...' 或 sheet.insertRule() 必须等 JS bundle 解析、执行、走到组件 render 阶段才触发。这意味着首屏关键样式被卡在 JS 主线程里,LCP 直接受拖累。
常见现象:Lighthouse 报 “Eliminate render-blocking resources”,且 Render Tree Construction 阶段耗时异常高;SSR 场景下漏掉服务端样式提取,直接导致 FOUC 或 CLS > 0.25。
每次渲染都可能触发同步 DOM 操作
CSS-in-JS 库(如 styled-components、@emotion/react)在组件 mount 或 props 变化时,会同步做:字符串插值 → 哈希计算 → 查重 → 创建/复用 <style> 标签 → 调用 insertRule()。这些全是主线程同步任务,无法中断。
高频场景下(如滚动卡片列表、实时颜色切换),insertRule() 调用堆叠明显,Chrome Performance 面板中常看到大量绿色 layout 任务,React DevTools 显示 commit 阶段占比超 40%。
立即学习“前端免费学习笔记(深入)”;
- 错误写法:
css={theme => ({ color: theme.text })}—— 每次 render 都生成新对象,强制重注入 - 正确做法:静态样式外提;动态部分用 CSS 变量 +
className切换
缓存与复用机制天然失效
传统 CSS 文件内容稳定,Cache-Control: public, max-age=31536000 下 CDN 缓存命中率极高;而 CSS-in-JS 注入的 <style> 内容依赖 JS 执行顺序、环境变量、甚至随机 salt,一次无关代码改动就可能导致整页样式 hash 全变。
后果很实际:用户每次更新 JS bundle,都得重新下载全部样式 —— 即使视觉上毫无变化。构建工具(Webpack/Vite)默认不感知这部分内容,也无对应 long-term caching 策略。
容易被忽略的一点:useInsertionEffect 虽能优化注入时机,但它本身不解决缓存问题;若未配合哈希 key 复用已有 <style> 标签,高频渲染下反而加剧内存分配压力。



















