emotion 不自动优化 css 性能,需正确启用缓存、提取和编译机制;避免在 render 中重复调用 styled 或 css;ssr 必须提取关键 css 防 fouc;慎用 @emotion/babel-plugin;与 tailwind 共用时需注意 purgecss 配置及样式注入顺序。

Emotion 本身不自动优化 CSS 运行性能,关键在于你是否启用并正确使用它的缓存、提取和编译机制。盲目用 css 函数高频生成样式,反而会拖慢渲染。
避免在 render 中重复调用 styled 或 css
每次调用 styled.div 或 css({}) 都会触发哈希计算和 class 注册。如果写在组件函数体顶层(非 static),React 每次 re-render 都会新建一个组件或样式对象:
- ❌ 错误写法:
const Button = styled.button`color: ${props => props.primary ? 'blue' : 'gray'};`放在组件内部; - ✅ 正确做法:把
styled组件定义在模块顶层,或用useMemo包裹动态css调用; - ⚠️ 注意:
css不做去重,相同对象多次调用仍生成不同 class;styled内部有哈希缓存,但新函数实例(如箭头函数)仍算“新组件”。
服务端渲染必须提取关键 CSS,否则 FOUC 无法避免
Next.js 或 Remix 等 SSR 框架里,仅靠 CacheProvider 不够。客户端 hydration 前若没注入初始样式,就会闪屏:
- Next.js 用户:在
getServerSideProps中调用@emotion/server/renderStylesToString,把返回的styles插入 HTML 的<style></style>标签; - Remix 用户:需配合
createEmotionCache+CacheProvider,且确保 root route 的响应头含Content-Type: text/html; - ⚠️ 常见坑:服务端 cache 实例未隔离,多个请求共用同一 cache 导致样式污染;客户端初始化
CacheProvider时 key 与服务端不一致,hydrate 失败。
慎用 Babel 插件 @emotion/babel-plugin
它能让模板字符串支持嵌套(如 &:hover),但代价是构建阶段额外解析,且在某些 monorepo 场景下易漏编译:
- ✅ 适合:纯单包项目、需要大量嵌套伪类且不介意构建变慢;
- ❌ 不适合:pnpm + changesets 工作流、CI 构建环境未统一配置插件;
- 替代方案:改用对象语法
css({ '&:hover': { color: 'red' } }),兼容性更好,无需插件; - ⚠️ 注意:对象语法中伪元素必须写全(
'&::before'),不能简写为'&:before',否则解析失败。
与 Tailwind 共用时,PurgeCSS 配置容易漏掉 Emotion 类名
Emotion 生成的 class 名是运行时哈希值(如 css-1a2b3c),PurgeCSS 默认只扫描源码中的字符串,无法识别这些动态 class:
- 必须显式配置 PurgeCSS 的
extractors,或改用glob扫描 dist 目录下的 JS 文件; - 更稳妥做法:禁用 PurgeCSS 对 Emotion 的清理,改用
@emotion/babel-plugin的importMap功能标记可安全删除的样式; - ⚠️ 最容易被忽略的一点:Emotion 和 Tailwind 的插入顺序影响优先级——Tailwind 的 utility class 若在 Emotion style 标签之后注入,会被覆盖。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











