性能优化 #

概述 #

性能优化是前端开发的重要环节。本文档介绍 Ant Design 项目的性能优化技巧和最佳实践。

组件优化 #

React.memo #

tsx
import { memo } from 'react';

const UserCard = memo(({ user }) => {
  return (
    <div>
      <h3>{user.name}</h3>
      <p>{user.email}</p>
    </div>
  );
});

export default UserCard;

useMemo #

tsx
import { useMemo } from 'react';

const UserList = ({ users }) => {
  const sortedUsers = useMemo(() => {
    return users.sort((a, b) => a.name.localeCompare(b.name));
  }, [users]);

  return (
    <div>
      {sortedUsers.map(user => (
        <UserCard key={user.id} user={user} />
      ))}
    </div>
  );
};

useCallback #

tsx
import { useCallback } from 'react';

const UserList = ({ users, onDelete }) => {
  const handleDelete = useCallback((id) => {
    onDelete(id);
  }, [onDelete]);

  return (
    <div>
      {users.map(user => (
        <UserCard key={user.id} user={user} onDelete={handleDelete} />
      ))}
    </div>
  );
};

列表优化 #

虚拟滚动 #

tsx
import { Table } from 'antd';

<Table
  virtual
  scroll={{ x: 2000, y: 500 }}
  columns={columns}
  dataSource={largeData}
/>

分页加载 #

tsx
import { Table } from 'antd';

<Table
  columns={columns}
  dataSource={data}
  pagination={{
    pageSize: 20,
    showSizeChanger: true,
  }}
/>

懒加载 #

路由懒加载 #

tsx
import { lazy, Suspense } from 'react';
import { Spin } from 'antd';

const Home = lazy(() => import('@/pages/Home'));
const User = lazy(() => import('@/pages/User'));

const router = (
  <Suspense fallback={<Spin />}>
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/user" element={<User />} />
    </Routes>
  </Suspense>
);

组件懒加载 #

tsx
import { lazy, Suspense } from 'react';
import { Spin } from 'antd';

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

const App = () => {
  const [show, setShow] = useState(false);

  return (
    <div>
      <Button onClick={() => setShow(true)}>显示</Button>
      {show && (
        <Suspense fallback={<Spin />}>
          <HeavyComponent />
        </Suspense>
      )}
    </div>
  );
};

图片优化 #

图片懒加载 #

tsx
import { Image } from 'antd';

<Image
  src="https://example.com/image.jpg"
  placeholder={<Spin />}
  preview={false}
/>

图片预览 #

tsx
import { Image } from 'antd';

<Image.PreviewGroup>
  <Image src="image1.jpg" />
  <Image src="image2.jpg" />
</Image.PreviewGroup>

请求优化 #

防抖 #

tsx
import { useDebounceFn } from 'ahooks';

const SearchInput = () => {
  const { run: handleSearch } = useDebounceFn(
    (value) => {
      console.log('搜索:', value);
    },
    { wait: 500 }
  );

  return <Input onChange={(e) => handleSearch(e.target.value)} />;
};

节流 #

tsx
import { useThrottleFn } from 'ahooks';

const ScrollList = () => {
  const { run: handleScroll } = useThrottleFn(
    () => {
      console.log('滚动事件');
    },
    { wait: 200 }
  );

  return <div onScroll={handleScroll}>内容</div>;
};

请求缓存 #

tsx
import { useRequest } from 'ahooks';

const UserList = () => {
  const { data, loading } = useRequest(userApi.getList, {
    cacheKey: 'user-list',
  });

  if (loading) return <Spin />;

  return (
    <div>
      {data?.map(user => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  );
};

状态优化 #

状态拆分 #

tsx
const UserForm = () => {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [phone, setPhone] = useState('');

  return (
    <Form>
      <Input value={name} onChange={e => setName(e.target.value)} />
      <Input value={email} onChange={e => setEmail(e.target.value)} />
      <Input value={phone} onChange={e => setPhone(e.target.value)} />
    </Form>
  );
};

状态提升 #

tsx
const UserList = () => {
  const [selectedId, setSelectedId] = useState(null);

  return (
    <div>
      <UserTable onSelect={setSelectedId} />
      <UserDetail id={selectedId} />
    </div>
  );
};

打包优化 #

代码分割 #

tsx
import { SplitChunks } from 'vite';

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
          antd: ['antd', '@ant-design/icons'],
        },
      },
    },
  },
});

Tree Shaking #

tsx
import { Button } from 'antd';
import { UserOutlined } from '@ant-design/icons';

最佳实践 #

1. 避免不必要的渲染 #

tsx
const UserCard = memo(({ user }) => {
  return <div>{user.name}</div>;
}, (prevProps, nextProps) => {
  return prevProps.user.id === nextProps.user.id;
});

2. 合理使用 key #

tsx
{users.map(user => (
  <UserCard key={user.id} user={user} />
))}

3. 避免内联函数 #

tsx
const handleClick = useCallback(() => {
  console.log('clicked');
}, []);

<Button onClick={handleClick}>点击</Button>

4. 合理使用 Context #

tsx
const UserContext = createContext();

const UserProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  const value = useMemo(() => ({ user, setUser }), [user]);

  return (
    <UserContext.Provider value={value}>
      {children}
    </UserContext.Provider>
  );
};

下一步 #

接下来学习 TypeScript 支持 组件!

最后更新:2026-03-28