构建时规划,运行时执行:解构 React Router 的 prerender 与 loader

static-data-loading

问题的核心是:为什么要有两个看起来都在读取文件的函数?

答案是:因为它们分别服务于两个完全不同阶段两个完全不同目的。一个是"构建阶段"的"规划者",另一个是"执行者",这个"执行者"不仅在"构建阶段"工作,也可能需要在"运行阶段"独立工作。

我们把这两个阶段拆开看:


阶段一:网站"构建"时 (Build Time)

想象一下你按下了"发布网站"的按钮。这时,你的电脑(服务器)开始执行一系列任务,把你的代码变成一个可以访问的网站。这个过程只发生这一次。

任务 A:规划要做哪些页面的"静态版本"

  • 谁来做? prerender 函数。
  • 它的目标是什么? 快速生成一个**"工作清单"**。清单上列出了所有需要提前生成好 HTML 的页面的 URL 地址。
  • 它怎么做? 它调用 readProductsFromCSVFile(),这个函数一口气读取整个 CSV 文件 ,拿到所有产品的 ID,然后组装成一个 URL 列表,比如 ['/products/1', '/products/2', '/products/3', ...]
  • 结果是什么? 一个简单的字符串数组prerender 的任务到此彻底结束。它不关心每个页面的内容是什么,只关心"有哪些页面要处理"。

任务 B:逐个执行清单,生成每个页面的 HTML

  • 谁来做? 构建工具会遍历"任务 A"生成的清单。对于清单上的每一项(比如 /products/1),它会调用 loader 函数。
  • 它的目标是什么? 获取这一个 特定页面(产品1)所需要的具体数据
  • 它怎么做? 它调用 getProductFromCSVFile('1')。这个函数拿着 ID 1,去 CSV 文件里只查找 ID 为 1 的那一行数据 ,然后返回 { id: '1', name: '键盘', ... }
  • 结果是什么? 一个包含产品1详细信息的对象 。构建工具拿到这个对象后,就能渲染出 product-1.html 文件。

然后构建工具继续处理清单的下一项 /products/2,再次调用 loader...如此循环。

小结:在构建时,prerender 是总指挥,只干一件事:列清单。loader 是具体工人,被总指挥叫一次,就去干一件具体的活:为指定的产品找数据。


阶段二:网站"运行"时 (Run Time)

现在,你的网站已经发布上线了。用户开始访问。

情况一:用户访问 /products/1

  • 服务器发现:"太好了!构建的时候已经生成了 product-1.html 文件。"
  • 服务器直接把这个现成的文件发给用户。速度极快。
  • 在这个过程中,loader 不会被调用。因为活儿已经干完了。

情况二:用户访问一个"意外"的 URL,比如 /products/101

  • 这个产品是网站发布后才添加到 CSV 文件里的,所以构建时并没有为它生成 HTML。
  • 服务器发现:"糟糕,没有 product-101.html 这个现成的文件。"
  • 这时,loader 函数就派上用场了!
  • 服务器会立即实时地 调用 loader 函数,并把 ID 101 传给它。
  • loader 再次执行它的老本行:调用 getProductFromCSVFile('101'),去 CSV 文件里找到产品 101 的数据。
  • 拿到数据后,服务器实时渲染页面,然后发给用户。

最终结论

现在您应该明白了:

  1. prerender 是一个一次性的规划者 :它只在"构建时"工作,目的是为了生成一个批处理清单。它没有能力处理单个、实时的请求。

  2. loader 是一个可复用的执行者 :它被设计成一个独立的、能处理单个请求的专家。

    • 在"构建时",它被 prerender 生成的清单驱动,一遍遍地被调用来完成批处理任务。
    • 在"运行时",它可以被服务器直接调用,来处理那些没有被预先构建的"意外"请求。

所以,它们都需要读取文件,但:

  • readProductsFromCSVFile 是为了 "广度":一次性拿到所有 ID,用于规划。
  • getProductFromCSVFile 是为了 "深度":一次只拿一个 ID 的全部详情,用于执行。

这种 "规划"和"执行"分离 的设计,才使得系统既能拥有静态预渲染的极高速度,又能灵活地处理动态、实时的请求。

相关推荐
人工智能训练6 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪6 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
2601_949593657 小时前
基础入门 React Native 鸿蒙跨平台开发:模拟智能音响
react native·react.js·harmonyos
xiaoqi9227 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233228 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头88219 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas1369 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
摇滚侠9 小时前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6
珑墨10 小时前
【Turbo】使用介绍
前端
军军君0110 小时前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three