应将 styled 组件定义提至模块顶层、避免 render 中动态创建、用 CSS 变量替代 props 函数式样式、禁用 css 工具函数在循环中调用、启用生产模式配置并用 Memory 面板检测 Detached HTMLStyleElement 增长。

不能靠压缩工具硬压,得从 Styled Components 的生成逻辑里砍冗余规则。它不是普通 CSS 文件,每条样式都绑定组件生命周期和 props 计算路径,压缩器根本不知道哪些规则是“动态生成但从未渲染”的。
避免 render 中动态创建 styled 组件
每次函数组件执行时调用 styled.div,都会触发新样式规则注入——哪怕只是改个颜色值。这些规则不会自动回收,积少成多就是几百个 <style> 标签。
- 错误写法:
const Button = () => { const StyledBtn = styled.button`color: ${props => props.theme.primary}`; return <StyledBtn>...</StyledBtn>; } - 正确做法:把
styled.button定义提到模块顶层,用 CSS 变量或className控制动态部分 - 高频列表场景(如
{items.map(...)})禁用css工具函数,否则每个 item 都生成独立规则
用 CSS 变量替代 props 函数式样式
写 background: ${props => props.bg} 会让 Styled Components 在运行时为每个不同 bg 值生成一条新规则;而用 background: var(--bg) + style={{ '--bg': color }},只保留一条静态规则。
- 静态规则数可控,devtools 里能看到
<style data-styled="xx">标签不再疯涨 - 主题切换时无需重生成样式,直接改根节点变量即可
- 注意 fallback 写法:
background: var(--bg, #007bff),避免变量未定义导致样式失效
关闭开发专用代码,禁用 SSR 不匹配警告
Styled Components v6 默认在 dev 模式下注入大量校验逻辑和 source map 注释,生产包里也残留部分判断分支。
立即学习“前端免费学习笔记(深入)”;
- Webpack 用户需在
babel-plugin-styled-components配置中加{ displayName: false, ssr: true, pure: true } - Vite 用户在
vite.config.ts的define中设process.env.NODE_ENV: 'production',否则 dev-only 代码无法被 tree-shaking - SSR 场景下确保客户端与服务端使用同一
StyleSheetManager实例,否则重复注入规则
真正难处理的是那些「看似没用、实则被动态 class 或 CMS 内容触发」的样式——它们不会出现在 Coverage 面板里,也不会被 PurgeCSS 扫到。上线前必须用 Memory 面板拍快照,盯着 Detached HTMLStyleElement 数量看路由切换后的增长趋势。


















