加载中...

常规的React项目(优化四)


React 的代码分割与懒加载

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


示例场景

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

  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;

关键点解释

  1. React.lazy
    • 用于动态加载组件。
    • 调用时返回一个 Promise,加载完成后返回组件。

const HomePage = lazy(() => import("./components/HomePage"));
  1. Suspense
    • 用于包裹懒加载的组件,必须设置一个 fallback 属性,表示加载期间的占位内容。

<Suspense fallback={<div>加载中...</div>}>
  <HomePage />
</Suspense>
  1. 按需加载:
    • 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;

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


文章作者: LYF
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LYF !
评论
  目录