通过 React.lazy 和 Suspense 实现动态加载组件,可以有效减少初始加载时间,提高页面的首屏性能。代码分割的核心思想是将大文件拆分为多个小文件,按需加载,从而避免一次性加载过多内容。

示例场景

假设有一个应用包含以下三个页面组件:

  1. HomePage(主页)
  2. AboutPage(关于页)
  3. ContactPage(联系我们)

我们使用代码分割和懒加载实现按需加载页面组件。


代码示例

1. 项目结构

src/
  components/
    HomePage.tsx
    AboutPage.tsx
    ContactPage.tsx
  App.tsx
  index.tsx

2. 各页面组件
HomePage.tsx

import React from "react";

const HomePage = () => {
  return <h1>欢迎来到主页</h1>;
};

export default HomePage;
AboutPage.tsx

import React from "react";

const AboutPage = () => {
  return <h1>这是关于页面</h1>;
};

export default AboutPage;

ContactPage.tsx


import React from "react";

const ContactPage = () => {
  return <h1>联系我们页面</h1>;
};

export default ContactPage;

3. 主应用组件 App.tsx

App.tsx 中使用 React.lazySuspense 来实现代码分割和懒加载。


import React, { Suspense, lazy, useState } from "react";

// 动态加载组件
const HomePage = lazy(() => import("./components/HomePage"));
const AboutPage = lazy(() => import("./components/AboutPage"));
const ContactPage = lazy(() => import("./components/ContactPage"));

const App = () => {
  const [currentPage, setCurrentPage] = useState<string>("home");

  // 根据当前页面选择显示的组件
  const renderPage = () => {
    switch (currentPage) {
      case "home":
        return <HomePage />;
      case "about":
        return <AboutPage />;
      case "contact":
        return <ContactPage />;
      default:
        return <HomePage />;
    }
  };

  return (
    <div>
      <nav>
        <button onClick={() => setCurrentPage("home")}>主页</button>
        <button onClick={() => setCurrentPage("about")}>关于</button>
        <button onClick={() => setCurrentPage("contact")}>联系我们</button>
      </nav>

      {/* Suspense 包裹懒加载的组件,设置加载中的 fallback */}
      <Suspense fallback={<div>加载中...</div>}>
        {renderPage()}
      </Suspense>
    </div>
  );
};

export default App;

关键点解释

React.lazy

  • 用于动态加载组件。
  • 调用时返回一个 Promise,加载完成后返回组件。
  • 
    const HomePage = lazy(() => import("./components/HomePage"));

Suspense

  • 用于包裹懒加载的组件,必须设置一个 fallback 属性,表示加载期间的占位内容。
  • 
    <Suspense fallback={<div>加载中...</div>}>
      <HomePage />
    </Suspense>

按需加载:

  • React.lazy 会在用户真正访问到某个页面时,才加载对应的组件。
  • 这样可以减少初始加载的 JS 文件体积,从而优化页面首屏加载性能。

验证效果

  1. 初始加载:打开应用时,只有主框架和当前页面的 JS 文件被加载。
  2. 切换页面:当用户点击导航按钮时,React 会按需加载对应页面的组件文件。
  3. 性能提升:通过开发者工具可以看到按需加载的 JS 文件大小和加载时机,从而验证性能优化效果。

注意事项

  1. Suspensefallback 占位内容:可以设计为用户友好的加载动画或提示,而不是简单的文本。
  2. 错误处理:如果懒加载的组件加载失败,可以使用 React Error Boundary 捕获错误并显示错误提示。
  3. 搭配路由:在实际项目中,通常会与路由库(如 react-router)结合使用,实现页面切换时的动态加载。

扩展示例:与 react-router 配合

如果你的项目使用 react-router,可以结合 React.lazy 实现路由的代码分割:


import React, { Suspense, lazy } from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

const HomePage = lazy(() => import("./components/HomePage"));
const AboutPage = lazy(() => import("./components/AboutPage"));
const ContactPage = lazy(() => import("./components/ContactPage"));

const App = () => {
  return (
    <Router>
      <Suspense fallback={<div>加载中...</div>}>
        <Routes>
          <Route path="/" element={<HomePage />} />
          <Route path="/about" element={<AboutPage />} />
          <Route path="/contact" element={<ContactPage />} />
        </Routes>
      </Suspense>
    </Router>
  );
};

export default App;

通过以上方法,初始加载只包含主框架的代码,页面组件会按需加载,从而进一步优化性能!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐