Skip to content

WIVSW/rsc-ssr-perf-test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SSR performance comparison: React Server Components vs streaming SSR

This repo demonstrates the difference in server-side rendering performance between React Server Components (RSC) and standard streaming SSR.

Run locally

To reproduce the benchmark, clone the repo and run:

  • nvm use
  • npm ci
  • npm run build
  • npm start

In a separate terminal, start the benchmark:

  • npm test

Benchmark results

The tests hit a Node.js server that renders a list of 10,000 items.

The benchmark uses autocannon with 50 concurrent connections and reports latency and requests per second (RPS).

The project uses Parcel for bundling, but results should be similar with other RSC bundlers or frameworks.

Regular SSR

Route: /ssr/regular Serves standard streaming SSR using renderToPipeableStream.

npx autocannon -c 50 -d 10 --renderStatusCodes --excludeErrorStats http://localhost:3000/ssr/regular 

Running 10s test @ http://localhost:3000/ssr/regular
50 connections

┌─────────┬───────┬────────┬────────┬────────┬───────────┬───────────┬─────────┐
│ Stat    │ 2.5%  │ 50%    │ 97.5%  │ 99%    │ Avg       │ Stdev     │ Max     │
├─────────┼───────┼────────┼────────┼────────┼───────────┼───────────┼─────────┤
│ Latency │ 65 ms │ 145 ms │ 245 ms │ 298 ms │ 150.31 ms │ 170.27 ms │ 3378 ms │
└─────────┴───────┴────────┴────────┴────────┴───────────┴───────────┴─────────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg     │ Stdev  │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼────────┼─────────┤
│ Req/Sec   │ 308     │ 308     │ 331     │ 336     │ 329.1   │ 7.69   │ 308     │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼────────┼─────────┤
│ Bytes/Sec │ 39.9 MB │ 39.9 MB │ 42.9 MB │ 43.5 MB │ 42.6 MB │ 999 kB │ 39.9 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴────────┴─────────┘
┌──────┬───────┐
│ Code │ Count │
├──────┼───────┤
│ 200  │ 3291  │
└──────┴───────┘

Req/Bytes counts sampled once per second.
# of samples: 10

3k requests in 10.02s, 426 MB read

SSR of a Server Component

Route: /ssr/rsc Renders a Server Component to HTML.

This type of rendering is not provided by React out of the box and it’s implemented in the frameworks:

  1. Render the Flight stream
  2. Render the Fizz stream from the Flight stream data
  3. Inject the Flight data into the HTML for client hydration
npx autocannon -c 50 -d 10 --renderStatusCodes --excludeErrorStats http://localhost:3000/ssr/rsc

Running 10s test @ http://localhost:3000/ssr/rsc
50 connections


┌─────────┬────────┬────────┬─────────┬─────────┬───────────┬────────────┬─────────┐
│ Stat    │ 2.5%   │ 50%    │ 97.5%   │ 99%     │ Avg       │ Stdev      │ Max     │
├─────────┼────────┼────────┼─────────┼─────────┼───────────┼────────────┼─────────┤
│ Latency │ 133 ms │ 571 ms │ 4814 ms │ 7858 ms │ 760.73 ms │ 1133.58 ms │ 9261 ms │
└─────────┴────────┴────────┴─────────┴─────────┴───────────┴────────────┴─────────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg     │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Req/Sec   │ 19      │ 19      │ 26      │ 42      │ 29.2    │ 6.99    │ 19      │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Bytes/Sec │ 10.8 MB │ 10.8 MB │ 14.8 MB │ 23.8 MB │ 16.6 MB │ 3.96 MB │ 10.8 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘
┌──────┬───────┐
│ Code │ Count │
├──────┼───────┤
│ 200  │ 292   │
└──────┴───────┘

Req/Bytes counts sampled once per second.
# of samples: 10
368 requests in 10.02s, 166 MB read
26 errors (26 timeouts)

Flight renderer

Route: /only/flight Renders the Server Component as Flight (JSON) only.

npx autocannon -c 50 -d 10 --renderStatusCodes --excludeErrorStats http://localhost:3000/only/flight

Running 10s test @ http://localhost:3000/only/flight
50 connections


┌─────────┬───────┬────────┬─────────┬─────────┬───────────┬───────────┬─────────┐
│ Stat    │ 2.5%  │ 50%    │ 97.5%   │ 99%     │ Avg       │ Stdev     │ Max     │
├─────────┼───────┼────────┼─────────┼─────────┼───────────┼───────────┼─────────┤
│ Latency │ 58 ms │ 302 ms │ 1778 ms │ 5944 ms │ 419.79 ms │ 888.33 ms │ 9855 ms │
└─────────┴───────┴────────┴─────────┴─────────┴───────────┴───────────┴─────────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg     │ Stdev  │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼────────┼─────────┤
│ Req/Sec   │ 102     │ 102     │ 104     │ 108     │ 104.7   │ 2.01   │ 102     │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼────────┼─────────┤
│ Bytes/Sec │ 36.5 MB │ 36.5 MB │ 37.3 MB │ 38.7 MB │ 37.5 MB │ 709 kB │ 36.5 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴────────┴─────────┘
┌──────┬───────┐
│ Code │ Count │
├──────┼───────┤
│ 200  │ 1047  │
└──────┴───────┘

Req/Bytes counts sampled once per second.
# of samples: 10

1k requests in 10.02s, 375 MB read
5 errors (5 timeouts)

Fizz renderer

Route: /only/fizz Renders the Server Component via Fizz using cached Flight data, skipping the initial Flight request.

npx autocannon -c 50 -d 10 --renderStatusCodes --excludeErrorStats http://localhost:3000/only/fizz

Running 10s test @ http://localhost:3000/only/fizz
50 connections


┌─────────┬───────┬────────┬────────┬─────────┬───────────┬───────────┬─────────┐
│ Stat    │ 2.5%  │ 50%    │ 97.5%  │ 99%     │ Avg       │ Stdev     │ Max     │
├─────────┼───────┼────────┼────────┼─────────┼───────────┼───────────┼─────────┤
│ Latency │ 41 ms │ 143 ms │ 287 ms │ 2559 ms │ 180.17 ms │ 421.98 ms │ 5525 ms │
└─────────┴───────┴────────┴────────┴─────────┴───────────┴───────────┴─────────┘
┌───────────┬─────┬──────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│ Stat      │ 1%  │ 2.5% │ 50%     │ 97.5%   │ Avg     │ Stdev   │ Min     │
├───────────┼─────┼──────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Req/Sec   │ 0   │ 0    │ 331     │ 341     │ 274.9   │ 120.24  │ 74      │
├───────────┼─────┼──────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Bytes/Sec │ 0 B │ 0 B  │ 42.9 MB │ 44.2 MB │ 35.6 MB │ 15.6 MB │ 9.58 MB │
└───────────┴─────┴──────┴─────────┴─────────┴─────────┴─────────┴─────────┘
┌──────┬───────┐
│ Code │ Count │
├──────┼───────┤
│ 200  │ 2749  │
└──────┴───────┘

Req/Bytes counts sampled once per second.
# of samples: 10

3k requests in 10.02s, 356 MB read

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published