Repository navigation
perf(rsc): add a Flight payload deserialization benchmark #1319
Description
Related plugin
Description
Next.js 16.2 highlighted a React Server Components rendering improvement that came from changing React Flight payload parsing from a JSON.parse reviver to a plain parse followed by a JavaScript walk. React's benchmark for the upstream change reported roughly 72–78% faster chunk deserialization, and Next.js reported 25–60% faster HTML rendering in representative applications.
@vitejs/plugin-rsc delegates Flight decoding to react-server-dom-webpack, so it should inherit the optimization when the matching React packages include it. However, this repository currently has no benchmark that shows the cost of Flight deserialization or makes a stable-versus-canary React comparison possible. The recently added performance-track example verifies React performance spans, but it intentionally tests instrumentation rather than decoder throughput.
A focused benchmark would help us:
- verify that
@vitejs/plugin-rscwrappers do not add a regression aroundcreateFromReadableStream(); - see when upstream React decoder improvements reach the plugin's default vendored version;
- compare matching stable and canary React package sets before changing the vendored version;
- distinguish Flight decoding time from server-component rendering and React DOM HTML rendering.
Suggested solution
Add a small RSC performance benchmark/fixture with representative payloads, for example:
- a small component tree;
- a table or list with about 1,000 items;
- nested Suspense boundaries;
- a larger text/content payload.
For each case, measure the relevant phases separately where practical:
- RSC render to a Flight stream;
- Flight consumption through
@vitejs/plugin-rsc/ssrand/or the browser client wrapper; - optional React DOM HTML rendering of the decoded tree.
The runner should warm up each case, take multiple samples, and report stable statistics such as median and p95. It should support the repository's existing pnpm override-react <version> workflow so the same fixture can be run with matching stable and canary packages.
Initially this can be an informational local or manually triggered benchmark rather than a strict CI threshold, avoiding noisy failures while establishing baselines.
This proposal is for measurement infrastructure; it should not copy React's parser into the plugin or switch users to canary packages automatically.
Alternative
Rely only on React's upstream benchmark. That proves the parser optimization itself, but it does not exercise this plugin's wrappers, vendored-version selection, or end-to-end RSC → SSR pipeline.
Additional context
- Next.js 16.2 faster rendering: https://nextjs.org/blog/next-16-2#faster-rendering
- React implementation and benchmark: [Server Components] Walk parsed JSON instead of using reviver for parsing RSC payload react/react#35776
- Existing performance-track example: https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-rsc/examples/performance-track
- Related but separate caching proposal: create official
"use cache"plugin #859 - Related but separate debug-channel proposal: Create debug channel example #1306
Validations
- Follow the Code of Conduct.
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue requesting the same feature.
Activity
hi-ogawa commentedon Jul 27, 2026
There shouldn't be any difference for server component only workload. The bundler difference appears only in client/server reference handling (
use clientcomponent anduse serverfunciton), so that's the differentiator. Another differentiator would be Node stream based API #1162Please feel free to create a benchmark. It's welcome but I don't think we'll have it inside the repo.
(I'll move this to discussion but it looks like github "convert to discussion" is broken, so commenting it here)