应直接用 styled 或 useMemo 包裹 css,避免 render 中新建对象导致缓存失效;props 需基础类型以保证更新;嵌套伪类须用 styled 模板或 css 对象语法;SSR 需服务端提取+客户端复用+hydration 前重置缓存。

直接用 styled,别在组件内部反复调用 css;动态逻辑必须稳定引用、可序列化、不触发重复哈希——否则性能损耗比传统 CSS 还高。
为什么在 render 里调用 css({}) 会变慢?
每次渲染都新建对象,Emotion 就无法命中缓存:哈希重算、序列化重跑、<style> 标签反复插入。DevTools 里能看到一堆 .css-abc123 冗余规则,低端设备卡顿明显。
- 错误写法:
const s = css({ color: props.color })放在函数组件体内部 - 正确做法:用
useMemo(() => css({ color: props.color }), [props.color])包裹,依赖项只含真正影响样式的字段 - 更轻量替代:简单值切换优先走 CSS 变量,比如
style={{ '--text-color': props.color }}+ 静态css规则
styled 组件怎么写才能响应 props 更新?
styled 天然支持 props 驱动样式,但必须保证传入的 props 是可序列化的基础类型(string/number/boolean),否则浅比较失效,样式就不更新。
- ✅ 正确:
styled.button(({ size, variant }) => ({ fontSize: size === 'lg' ? '1.25rem' : '1rem', backgroundColor: variant === 'primary' ? '#007bff' : '#6c757d' })) - ❌ 错误:
styled.button(props => { return { ... } })没用括号包裹返回对象,JS 隐式返回undefined - ⚠️ 注意:避免传对象或函数引用,如
theme={{ primary: '#007bff' }}—— 引用不变,样式就卡死
嵌套伪类(如 &:hover)怎么写才生效?
Emotion 默认不解析模板字符串里的嵌套语法,css`&:hover { color: red; }` 是无效的,会被当作文本忽略。
立即学习“前端免费学习笔记(深入)”;
- ✅ 正确方式一:用
styled模板字符串,styled.div`&:hover { opacity: 0.8; }` - ✅ 正确方式二:用
css对象语法,css({ '&:hover': { opacity: 0.8 } }) - ⚠️ 注意:
&::before必须写全,不能简写为&:before,否则解析失败
SSR 场景下动态样式为啥会闪屏或错乱?
服务端没提取样式、客户端没复用 cache、或者 hydration 前没清空缓存,三者任一出问题都会导致首屏无样式或 layout shift。
- 服务端必须调用
renderStylesToString或extractCritical,把生成的css插入 HTML 的<head> - 客户端 hydration 前要执行
cache.reset()(仅 SSR 场景),否则服务端注入的规则和客户端新规则可能冲突 - Next.js 用户注意:
@emotion/server版本必须与@emotion/react主版本一致,混用会导致缓存 key 错位、内存占用翻倍
最常被忽略的是全局规则泄漏——global 和 keyframes 创建后永不自动清理,微前端卸载或主题切换时容易堆积,检查 cache.sheet.tags 数量是否持续增长就能定位。


















