HOW - prefetch 二级页面实践

文章目录

  • [方法一:使用 import()](#方法一:使用 import())
  • [方法二:使用 link rel="prefetch" 或 link rel="preload"](#方法二:使用 link rel="prefetch" 或 link rel="preload")
  • [方法三:借助 Vite 插件自动预取](#方法三:借助 Vite 插件自动预取)
  • 小结
  • 批量预加载

在 Vite + React 项目中,如果你希望在访问首页(index 页面)时提前预加载(prefetch)二级页面的资源,从而在用户点击进入时加快加载速度,有几种常见、有效的方式。


方法一:使用 import()

如果你的二级页面是通过 动态 import(代码分割) 实现的(这是 Vite 推荐的懒加载方式),那么你可以手动对它的资源进行预取(prefetch)。

比如你的路由是这样定义的

ts 复制代码
// router.tsx
import { lazy } from "react";

const IndexPage = lazy(() => import("./pages/Index"));
const AboutPage = lazy(() => import("./pages/About")); // 二级页面

export const routes = [
  { path: "/", element: <IndexPage /> },
  { path: "/about", element: <AboutPage /> },
];

你可以在 IndexPageuseEffect 中触发 import(),这样浏览器就会预加载资源(但不会执行)

ts 复制代码
// pages/Index.tsx
import { useEffect } from "react";

export default function Index() {
  useEffect(() => {
    // 预取 About 页面的资源
    import("./About");
  }, []);

  return (
    <div>
      <h1>首页</h1>
      <a href="/about">去 About</a>
    </div>
  );
}

这里 ./About 并不是指构建后的实际路径,而是与Index同一层级下的About.tsx。Vite 在打包时会自动把这个 import("./About") 替换成对 about-yyyy.js 的懒加载请求。你不需要知道它的真实文件名。

优点:

  • 简单好用,不需要额外依赖。
  • Vite 在 build 后会自动生成 chunk,对应资源会被预取。
  • 实际浏览器加载时,用户点击 /about 基本是即时打开。

注意:

  • 这种方式属于「预加载模块」,不是真正意义的浏览器 rel="prefetch" 标签。
  • 适合用在用户很大概率会访问的二级页面上。

如果你希望更明确地让浏览器在空闲时预取资源 ,可以在首页渲染时插入一个 <link> 标签

ts 复制代码
import { useEffect } from "react";

export default function Index() {
  useEffect(() => {
    const link = document.createElement("link");
    link.rel = "prefetch";
    link.href = "/assets/AboutPage.xxx.js"; // 构建后的 chunk 路径
    document.head.appendChild(link);
  }, []);

  return <h1>首页</h1>;
}

这种方式比较麻烦的是:

  • 你要知道 About 页面的构建产物路径(可以通过 manifest.json 或动态 import 的返回值获取)。
  • 更适合对静态资源(图片、视频、大文件)做预加载。

方法三:借助 Vite 插件自动预取

还有一种自动化的方式是使用社区插件,例如 👉
vite-plugin-pwa(适合离线场景)
vite-plugin-prefetch(更灵活的 prefetch)

vite.config.ts 中配置:

ts 复制代码
import prefetch from "vite-plugin-prefetch";

export default {
  plugins: [
    prefetch({
      rel: "prefetch",
      include: ["about"], // 你想要预取的 chunk 名称
    }),
  ],
};

优点

  • 自动插入 <link rel="prefetch">
  • 不需要在组件中写逻辑。

小结

方式 特点 适合场景
import() 预加载 简单、推荐 二级页面懒加载
<link rel="prefetch"> 控制更细,但需路径 预取静态资源
React Router 预加载 更规范 使用 react-router v6+
Vite 插件自动化 零侵入 大型项目,多个页面

批量预加载

如果你有多个页面,也可以并行预加载:

ts 复制代码
useEffect(() => {
  Promise.all([
    import("./About"),
    import("./Contact"),
    import("./Help"),
  ]);
}, []);

当然也可以封装一个工具函数:

ts 复制代码
// utils/prefetchRoutes.ts
export async function prefetchRoutes(paths: string[]) {
  const prefetchMap: Record<string, () => Promise<any>> = {
    "/about": () => import("../pages/About"),
    "/contact": () => import("../pages/Contact"),
    "/help": () => import("../pages/Help"),
  };

  await Promise.all(paths.map((path) => prefetchMap[path]?.()));
}

// Index.tsx
import { useEffect } from "react";
import { prefetchRoutes } from "../utils/prefetchRoutes";

export default function Index() {
  useEffect(() => {
    prefetchRoutes(["/about", "/contact", "/help"]);
  }, []);

  return (
    <div>
      <h1>首页</h1>
      <a href="/about">About</a>
      <a href="/contact">Contact</a>
      <a href="/help">Help</a>
    </div>
  );
}

注意,如果二级页面特别多,比如十几个甚至几十个,一次性全部预加载反而会拖慢首页加载。

推荐策略:

  1. 对访问概率高的页面在首页预加载(比如「关于我」)。
  2. 对不常访问的页面延迟到用户第一次 hover / focus 时再预加载。
ts 复制代码
<a
  href="/about"
  onMouseEnter={() => import("./About")}
>
  About
</a>

这样用户第一次将鼠标移到链接上时,就已经预取完成,点击时是"秒开"。

最推荐的实践组合是:

  1. 在首页 useEffect 中预加载 1~3 个高频页面。
  2. 对其余页面用 hover 延迟预加载。
  3. 保持首页首屏加载轻量。
相关推荐
我命由我123454 小时前
PDFBox - PDDocument 与 byte 数组、PDF 加密
java·服务器·前端·后端·学习·java-ee·pdf
EF@蛐蛐堂4 小时前
WUJIE VS QIANKUN 微前端框架选型(一)
前端·vue.js·微服务·架构
前端OnTheRun4 小时前
React18学习笔记(六) React中的类组件,极简的状态管理工具zustand,React中的Typescript
react.js·组件·
咚咚咚小柒4 小时前
【前端】用el-popover做通用悬停气泡(可设置弹框宽度)
前端·javascript·vue.js·elementui·html·scss
Ares-Wang4 小时前
CSS3》》 transform、transition、translate、animation 区别
前端·css·css3
fsnine4 小时前
Python Web框架对比与模型部署
开发语言·前端·python
广州华水科技4 小时前
单北斗GNSS形变监测系统在桥梁安全中的应用与技术解析
前端
打小就很皮...5 小时前
ShowCountCard 功能迭代:新增周月对比属性,完善数据可视化场景
前端·react.js·信息可视化
IT_陈寒5 小时前
Redis性能翻倍的7个冷门技巧:从P5到P8都在偷偷用的优化策略!
前端·人工智能·后端