React 路由懒加载入门:提升首屏性能的第一步

React 中的路由懒加载入门:提升首屏性能的第一步

在现代前端开发中,React 应用的体积越来越大 ,尤其是随着功能的不断扩展,首屏加载时间也随之增加。为了优化用户体验和提高应用性能,路由懒加载(Lazy Loading Routes) 成为了一种非常重要的技术手段。

本文将带你深入了解如何在 React 项目中实现路由懒加载,并结合 React.lazySuspenseReact Router 实现高效的代码分割与按需加载。

一、什么是路由懒加载?

路由懒加载指的是在用户访问某个路由时,才动态加载对应的组件资源。这种方式可以避免一次性加载整个应用的所有代码,而是根据需要分块加载,从而显著减少初始加载时间。

  • 没有使用路由懒加载的情况

    根组件组件

    jsx 复制代码
    import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
    import Home from './pages/Home'
    import About from './pages/About'
    import Login from './pages/Login'
    import Navigation from './components/Navigation'
    import './App.css'
    
    function App() {
    
      return (
        <>
          <Router>
            <Navigation />
            <Routes>
              <Route path="/" element={<Home />} />
              <Route path="/about" element={<About />} />
              <Route path="/login" element={<Login />} />
            </Routes>
          </Router>
        </>
      )
    }
    export default App

    Home组件

    jsx 复制代码
    console.log('加载Home组件')
    export default function Home() {
      console.log('Home')
      return (
        <div>
          <h1>Home</h1>
          <p>这是Home页面</p>
        </div>
      );
    }

    About组件

    jsx 复制代码
    console.log('加载About组件')
    export default function About() {
      console.log("About组件");
      return (
        <div>
          <h1>About</h1>
          <p>这是About页面</p>
        </div>
      );
    }

    Login组件

    jsx 复制代码
    console.log('加载Login组件')
    export default function Login() {
      console.log('Login')
      return (
        <div>
          <h1>登录</h1>
        </div>
      );
    }

    输出情况

    复制代码
    加载Home组件
    加载About组件
    加载Login组件
    Home

    这是因为当使用import导入组件时,浏览器或打包工具(如 Webpack、Vite)会加载并执行整个 .jxs 文件(不会执行组件函数)。所以这些组件都加载并执行了,若应用中存在多个路由页面时,如果所有组件都在首页一次性加载,会导致页面加载速度变慢,影响用户体验。

  • 使用路由懒加载的情况

    jsx 复制代码
    import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
    import Navigation from "./components/Navigation";
    import "./App.css";
    import { lazy, Suspense } from "react";
    
    function App() {
      const Home = lazy(() => import("./pages/Home"));
      const About = lazy(() => import("./pages/About"));
      const Login = lazy(() => import("./pages/Login"));
      return (
        <>
          <Router>
            <Navigation />
            <Suspense fallback={<div>Loading...</div>}>
              <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/about" element={<About />} />
                <Route path="/login" element={<Login />} />
              </Routes>
            </Suspense>
          </Router>
        </>
      );
    }
    export default App;

    输出情况

    复制代码
    加载Home组件
    Home

    从输出情况可以看出 除了Home组件加载了,其他组件都没有加载

二、React 中实现懒加载的核心 API

  1. React.lazy

    React.lazy 是 React 提供的一个用于延迟加载组件的函数。它介绍一个函数作为参数,这个函数返回import()动态导入。lazy返回的是一个特殊的 React 组件,这个组件在首次渲染时才会真正加载。

    jsx 复制代码
    import { lazy } from "react";
    const Home = lazy(() => import('./Home'));
  2. <Suspense>

    由于懒加载组件是异步加载的,在加载完成之前,我们需要显示一个"加载中"的状态 ,为用户提供良好的体验。<Suspense> 就是用来包裹这些懒加载组件并提供加载状态的组件。

    jsx 复制代码
    import React, { Suspense } from 'react';
    
    function App() {
      return (
        <Suspense fallback="Loading...">
          <Home />
        </Suspense>
      );
    }
  3. 执行逻辑

    首次渲染 时React 会执行 () => import('./Home'),然后开始异步加载 Home 的代码,在加载期间显示 <Suspense>fallback UI。加载完成后 动态导入的组件会替换这个占位组件并渲染实际的 SomeComponent

三、在 React Router 中实现路由懒加载

如果你使用的是 React Router v6+ ,可以通过组合 React.lazy + Suspense 来实现懒加载路由。

示例:基本结构

jsx 复制代码
import React, { Suspense } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

// 懒加载页面组件
const Home = React.lazy(() => import('./pages/Home'));
const About = React.lazy(() => import('./pages/About'));
const Contact = React.lazy(() => import('./pages/Contact'));

function App() {
  return (
    <Router>
      <Suspense fallback="Loading...">
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
          <Route path="/contact" element={<Contact />} />
        </Routes>
      </Suspense>
    </Router>
  );
}

export default App;

这样,每个页面组件都会在用户访问对应路径时才加载,而不是一开始就全部加载。

四、增强体验:添加加载状态与错误处理

  1. 自定义加载组件

    你可以自定义一个通用的加载提示组件:

    jsx 复制代码
    function Loading() {
      return <div className="loading">加载中,请稍候...</div>;
    }

    然后在 Suspense 中使用:

    jsx 复制代码
    <Suspense fallback={<Loading />}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  2. 错误边界(Error Boundary)

    懒加载过程中可能会出现网络问题或其他错误,建议使用错误边界来捕获异常,避免页面崩溃。

    jsx 复制代码
    class ErrorBoundary extends React.Component {
      state = { hasError: false };
    
      static getDerivedStateFromError(error) {
        return { hasError: true };
      }
    
      render() {
        if (this.state.hasError) {
          return <div>页面加载出错,请刷新重试。</div>;
        }
        return this.props.children;
      }
    }

    结合使用:

    jsx 复制代码
    <ErrorBoundary>
      <Suspense fallback={<Loading />}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </Suspense>
    </ErrorBoundary>
相关推荐
会跑的葫芦怪12 分钟前
若依Vue 项目多子路径配置
前端·javascript·vue.js
2601_9495936526 分钟前
基础入门 React Native 鸿蒙跨平台开发:模拟智能音响
react native·react.js·harmonyos
xiaoqi9221 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233222 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头88213 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas1363 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
摇滚侠3 小时前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6
珑墨4 小时前
【Turbo】使用介绍
前端
军军君014 小时前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three
xiaoqi9225 小时前
React Native鸿蒙跨平台如何实现分类页面组件通过searchQuery状态变量管理搜索输入,实现了分类的实时过滤功能
javascript·react native·react.js·ecmascript·harmonyos