性能优化 #

一、渲染优化 #

1.1 避免内联函数 #

jsx
import styled from 'styled-components';

const BadButton = styled.button`
  padding: ${props => {
    switch (props.size) {
      case 'small': return '8px 16px';
      case 'large': return '16px 32px';
      default: return '12px 24px';
    }
  }};
`;

const getPadding = (size) => {
  switch (size) {
    case 'small': return '8px 16px';
    case 'large': return '16px 32px';
    default: return '12px 24px';
  }
};

const GoodButton = styled.button`
  padding: ${props => getPadding(props.size)};
`;

1.2 使用 useMemo 缓存 #

jsx
import { useMemo } from 'react';
import styled from 'styled-components';

const ExpensiveComponent = styled.div`
  ${props => props.$computedStyles}
`;

function ParentComponent({ data }) {
  const computedStyles = useMemo(() => {
    return css`
      background: ${data.color};
      padding: ${data.padding};
    `;
  }, [data.color, data.padding]);

  return <ExpensiveComponent $computedStyles={computedStyles} />;
}

1.3 减少样式组件数量 #

jsx
import styled from 'styled-components';

const Card = styled.div`
  padding: 24px;
  background: white;
  border-radius: 12px;
`;

const CardTitle = styled.h2`
  font-size: 24px;
  margin-bottom: 12px;
`;

const CardDescription = styled.p`
  color: #666;
  line-height: 1.6;
`;

const CardFooter = styled.div`
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #eee;
`;

const OptimizedCard = styled.div`
  padding: 24px;
  background: white;
  border-radius: 12px;

  h2 {
    font-size: 24px;
    margin-bottom: 12px;
  }

  p {
    color: #666;
    line-height: 1.6;
  }

  .footer {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid #eee;
  }
`;

二、样式计算优化 #

2.1 静态样式提取 #

jsx
import styled, { css } from 'styled-components';

const staticStyles = css`
  padding: 12px 24px;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
`;

const Button = styled.button`
  ${staticStyles}
  background: ${props => props.$primary ? '#667eea' : '#fff'};
  color: ${props => props.$primary ? '#fff' : '#667eea'};
`;

2.2 避免过度插值 #

jsx
const BadButton = styled.button`
  padding: ${props => props.$padding || '12px 24px'};
  margin: ${props => props.$margin || '0'};
  border-radius: ${props => props.$radius || '8px'};
  font-size: ${props => props.$fontSize || '16px'};
  background: ${props => props.$bg || '#667eea'};
`;

const GoodButton = styled.button`
  padding: 12px 24px;
  margin: 0;
  border-radius: 8px;
  font-size: 16px;
  background: #667eea;
  
  ${props => props.$variant === 'secondary' && css`
    background: transparent;
    border: 2px solid #667eea;
  `}
`;

2.3 使用 shouldForwardProp #

jsx
import styled from 'styled-components';

const Button = styled.button.withConfig({
  shouldForwardProp: (prop) => !['$variant', '$size', '$loading'].includes(prop),
})`
  padding: 12px 24px;
  background: ${props => props.$variant === 'primary' ? '#667eea' : '#fff'};
`;

三、组件设计优化 #

3.1 组件拆分 #

jsx
import styled from 'styled-components';
import { memo } from 'react';

const ExpensiveList = memo(styled.ul`
  list-style: none;
  padding: 0;
`);

const ExpensiveListItem = memo(styled.li`
  padding: 12px;
  border-bottom: 1px solid #eee;
  
  &:last-child {
    border-bottom: none;
  }
`);

function List({ items }) {
  return (
    <ExpensiveList>
      {items.map(item => (
        <ExpensiveListItem key={item.id}>{item.name}</ExpensiveListItem>
      ))}
    </ExpensiveList>
  );
}

3.2 条件渲染优化 #

jsx
import styled, { css } from 'styled-components';

const Card = styled.div`
  padding: 24px;
  background: white;
  border-radius: 12px;
  
  ${props => props.$elevated && css`
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  `}
  
  ${props => props.$interactive && css`
    cursor: pointer;
    transition: transform 0.2s;
    
    &:hover {
      transform: translateY(-4px);
    }
  `}
`;

const ElevatedCard = styled(Card)`
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
`;

const InteractiveCard = styled(ElevatedCard)`
  cursor: pointer;
  transition: transform 0.2s;
  
  &:hover {
    transform: translateY(-4px);
  }
`;

3.3 避免深度嵌套 #

jsx
const DeepNested = styled.div`
  .container {
    .header {
      .title {
        .text {
          color: red;
        }
      }
    }
  }
`;

const FlatStructure = styled.div`
  .title-text {
    color: red;
  }
`;

const TitleText = styled.span`
  color: red;
`;

四、包体积优化 #

4.1 按需导入 #

jsx
import styled from 'styled-components';
import { keyframes } from 'styled-components';

const fadeIn = keyframes`
  from { opacity: 0; }
  to { opacity: 1; }
`;

const FadeInBox = styled.div`
  animation: ${fadeIn} 0.5s ease;
`;

4.2 Babel 插件优化 #

json
{
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "displayName": false,
        "minify": true,
        "transpileTemplateLiterals": true,
        "pure": true
      }
    ]
  ]
}

4.3 代码分割 #

jsx
import { lazy, Suspense } from 'react';

const HeavyStyledComponent = lazy(() => import('./HeavyStyledComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <HeavyStyledComponent />
    </Suspense>
  );
}

五、样式表优化 #

5.1 减少动态样式 #

jsx
import styled, { css } from 'styled-components';

const buttonVariants = {
  primary: css`
    background: #667eea;
    color: white;
  `,
  secondary: css`
    background: transparent;
    color: #667eea;
    border: 2px solid #667eea;
  `,
};

const Button = styled.button`
  padding: 12px 24px;
  border-radius: 8px;
  cursor: pointer;
  
  ${props => buttonVariants[props.$variant] || buttonVariants.primary}
`;

5.2 合并相似样式 #

jsx
const BaseButton = styled.button`
  padding: 12px 24px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 600;
  transition: all 0.2s;
`;

const PrimaryButton = styled(BaseButton)`
  background: #667eea;
  color: white;
  border: none;
`;

const SecondaryButton = styled(BaseButton)`
  background: transparent;
  color: #667eea;
  border: 2px solid #667eea;
`;

5.3 使用 CSS 变量 #

jsx
import styled from 'styled-components';

const Card = styled.div`
  --card-padding: 24px;
  --card-radius: 12px;
  --card-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  
  padding: var(--card-padding);
  border-radius: var(--card-radius);
  box-shadow: var(--card-shadow);
  background: white;
  
  &:hover {
    --card-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  }
`;

六、运行时优化 #

6.1 避免重复创建 #

jsx
import styled, { css } from 'styled-components';

const createCardStyles = (variant) => css`
  padding: 24px;
  background: white;
  border-radius: 12px;
  
  ${variant === 'elevated' && css`
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  `}
`;

const cardStyles = {
  default: createCardStyles('default'),
  elevated: createCardStyles('elevated'),
};

const Card = styled.div`
  ${props => cardStyles[props.$variant || 'default']}
`;

6.2 缓存主题值 #

jsx
import styled from 'styled-components';
import { useMemo } from 'react';

function useThemedStyles() {
  const theme = useTheme();
  
  return useMemo(() => ({
    primary: theme.colors.primary,
    secondary: theme.colors.secondary,
  }), [theme.colors.primary, theme.colors.secondary]);
}

const Button = styled.button`
  background: ${props => props.$colors.primary};
`;

6.3 懒加载样式 #

jsx
import styled from 'styled-components';
import { useState, useEffect } from 'react';

const HeavyComponent = styled.div`
  ${props => props.$loaded && css`
    animation: ${heavyAnimation} 1s ease;
  `}
`;

function App() {
  const [loaded, setLoaded] = useState(false);
  
  useEffect(() => {
    setLoaded(true);
  }, []);
  
  return <HeavyComponent $loaded={loaded} />;
}

七、调试与监控 #

7.1 性能分析 #

jsx
import styled from 'styled-components';
import { Profiler } from 'react';

const Button = styled.button`
  padding: 12px 24px;
  background: #667eea;
  color: white;
`;

function onRenderCallback(
  id,
  phase,
  actualDuration,
  baseDuration,
  startTime,
  commitTime
) {
  console.log(`${id} ${phase} took ${actualDuration}ms`);
}

function App() {
  return (
    <Profiler id="Button" onRender={onRenderCallback}>
      <Button>Click me</Button>
    </Profiler>
  );
}

7.2 样式检查 #

jsx
import styled from 'styled-components';

if (process.env.NODE_ENV === 'development') {
  const originalCreateElement = styled.button;
  
  styled.button = (...args) => {
    const component = originalCreateElement(...args);
    console.log('Created styled component:', component.displayName);
    return component;
  };
}

八、最佳实践总结 #

8.1 性能检查清单 #

text
✅ 性能优化检查清单
├── 避免内联函数
├── 使用 useMemo 缓存计算
├── 提取静态样式
├── 减少样式组件数量
├── 使用 shouldForwardProp
├── 配置 Babel 插件
├── 避免深度嵌套选择器
├── 使用 CSS 变量
├── 按需导入
└── 代码分割

8.2 性能对比 #

text
优化前 vs 优化后

内联函数
├── 优化前: 每次渲染创建新函数
└── 优化后: 使用预定义函数

样式计算
├── 优化前: 每次渲染重新计算
└── 优化后: 使用 useMemo 缓存

包体积
├── 优化前: 完整包
└── 优化后: 按需导入 + 压缩

九、总结 #

性能优化要点速查表:

优化项 方法
渲染优化 避免内联函数、useMemo
样式计算 静态样式提取、减少插值
组件设计 拆分组件、条件渲染
包体积 Babel 插件、代码分割
样式表 CSS 变量、合并样式
运行时 缓存、懒加载

下一步:学习 TypeScript集成 掌握类型安全的样式开发。

最后更新:2026-03-28