如何用 Fizz 夹具测试 React 流式 SSR 的性能基线
【免费下载链接】reactThe library for web and native user interfaces.项目地址: https://gitcode.com/GitHub_Trending/re/react
React 仓库中的fixtures/fizz是一组用于验证 Fizz 服务端渲染的基本测试应用,其定位在 fixtures/fizz/README.md 中写得很明确:主要用来观察 legacyrenderToString与流式渲染两种实现的基线性能。如果你的目标是搭建一个可以反复对比「一次性字符串渲染」和「流式 SSR」表现的本地环境,这篇文章给出完整的操作步骤:从构建 React 产物,到启动夹具服务、切换 dev/prod 模式、调整延迟参数,以及判断服务是否按预期运行。
准备条件
- Node 版本要求:fixtures/fizz/package.json 的
engines字段声明"node": ">=14.9.0"。 - 夹具引用的是本地构建的 React 产物,而不是 npm 上的发布版。因此第一步必须在 React 仓库根目录执行:
npm run buildfixtures/fizz/README.md 明确说明「To reference a local build of React, first runnpm run buildat the root of the React project」。根目录package.json中的build脚本会生成build/oss-experimental产物,夹具的prestart/predev钩子正是把这份产物复制进自己的node_modules来引用。
启动开发模式
进入夹具目录并安装依赖、启动服务:
cd fixtures/fizz yarn yarn startyarn start通过concurrently同时拉起两个进程(见package.json的scripts):
start:server:以NODE_ENV=production环境变量用 nodemon 运行 server/server.js;start:bundler:用 nodemon 运行scripts/build.js的 webpack 构建。
按 README 的说明,start命令会以开发模式运行 webpack dev server 和服务端渲染服务器,并支持热加载。启动后服务端会打印监听日志:
Listening at 4000...默认端口是 4000,server.js中通过const PORT = process.env.PORT || 4000读取,如需更换端口可设置PORT环境变量。
访问三种渲染端点
server/server.js 暴露了四个路由,正好覆盖基线对比所需的实现:
| 路由 | 渲染方式 | 实现文件 |
|---|---|---|
/和/stream | 流式渲染(renderToPipeableStream) | server/render-to-stream.js |
/string | legacy 同步渲染(renderToString) | server/render-to-string.js |
/buffer | 用Writable累积完整 HTML 后再一次性发送 | server/render-to-buffer.js |
服务启动时会先执行waitForWebpack():在 webpack 产出build/main.js之前,请求会持续等待并打印「Could not find webpack build output. Will retry in a second...」,这是正常的等待现象,不是错误。
流式端点的行为要点(来自render-to-stream.js源码注释):
onShellReady时发送响应头并开始向响应流pipe数据;onAllReady表示完整渲染完成,可用于 SSG 或爬虫场景;- 若 shell 阶段出错,响应状态码为 500 并输出
<!doctype><p>Error</p>; - 存在一个
ABORT_DELAY定时器:到时间仍未完成则调用abort()放弃服务端渲染、回退到客户端渲染。源码注释写的是「Try lowering this to see the client recover」,即调低该值可以观察客户端接管恢复的过程。
调整延迟参数来观察不同延迟场景
三种渲染都会经过的延迟常量集中在 server/delays.js,文件注释是「Tweak these to play with different kinds of latency」:
// How long the data fetches on the server. exports.API_DELAY = 2000; // How long the server waits for data before giving up. exports.ABORT_DELAY = 10000; // How long serving the JS bundles is delayed. exports.JS_BUNDLE_DELAY = 4000;API_DELAY:模拟服务端数据请求的耗时;ABORT_DELAY:流式渲染放弃转客户端渲染前等待数据的时间;JS_BUNDLE_DELAY:JS bundle 下发的延迟。
修改后由于 nodemon 监控源码,服务会自动重启,重新请求/、/string、/stream三个端点即可在相同延迟条件下横向比较不同实现的输出节奏。
生产模式与重建 React 后的重跑
可选分支:如果不想用热加载的开发环境,而是模拟更接近正式部署的环境,README 给出的是:
yarn start:prod该命令会预先构建所有静态资源,然后启动一个托管 React 应用并服务静态资源的服务端渲染 HTTP 服务器(无热加载)。
一个容易踩的坑在 README 中用加粗标出:每次改动 React 并重新构建后,必须在fixtures/fizz目录重新运行yarn。原因是prestart钩子执行的是:
cp -r ../../build/oss-experimental/* ./node_modules/ && rm -rf node_modules/.cache只有在再次安装/启动时,新的 React 本地构建产物才会被复制进node_modules,否则你测的还是旧版构建。
如何判断运行结果与已知边界
- 启动成功的直接信号是终端出现
Listening at 4000...;随后访问http://localhost:4000/应能拿到流式渲染的 HTML 页面。 - 端口被占用时,
server.js会输出Port 4000 is already in use并退出(对应EADDRINUSE分支),需要先释放端口再启动。 - 流式渲染在 shell 出错时返回 500 和
<!doctype><p>Error</p>,onError会把错误打印到控制台(console.error(x))。 - 需要说明的边界:各渲染文件中硬编码了
assets = {'main.js': '/main.js', 'main.css': '/main.css'},源码注释是「In a real setup, you'd read it from webpack build stats」——它只是一个基线测试夹具,不是生产级 SSR 方案;package.json中的react/react-dom依赖在运行期实际被本地构建产物覆盖,用于观察行为而非验证发布版本。
完成一次完整的基线观察,顺序就是:根目录npm run build→fixtures/fizz下yarn→yarn start(或yarn start:prod)→ 分别访问/、/string、/buffer对比表现 → 修改 server/delays.js 观察不同延迟下的行为。改动 React 源码后记得回到fixtures/fizz重跑yarn再验证。
【免费下载链接】reactThe library for web and native user interfaces.项目地址: https://gitcode.com/GitHub_Trending/re/react
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考