Skip to content

Server-side rendering performance degradation with renderToPipeableStream #24232

Open
@SuperOleg39

Description

@SuperOleg39

Hello!

When switching from renderToString to renderToPipeableStream, I run load tests on the application, and found a decrease in server throughput, from 50 to 15 RPS, and an increase in response timings.
When profiling the CPU, I see a large overhead on the internal work of the stream, specifically the methods Writable.write and Writable.uncork.
All these method calls together take more than twice as much CPU time (about 50-60ms) as rendering my test page (about 15-20ms)

Also, I don't want to give the HTML to the client in the stream, this approach has some disadvantages.
So I have to buffer the data, and it slows down the application a bit more.

CPU profiler in production mode:

Снимок экрана 2022-03-31 в 16 21 00

CPU profiler in development mode:

Снимок экрана 2022-03-31 в 16 21 36

My custom Writable stream with buffering:

class HtmlWritable extends Writable {
  chunks = [];
  html = '';

  getHtml() {
    return this.html;
  }

  _write(chunk, encoding, callback) {
    this.chunks.push(chunk);
    callback();
  }

  _final(callback) {
    this.html = Buffer.concat(this.chunks).toString();
    callback();
  }
}

And rendering flow:

import { renderToPipeableStream } from 'react-dom/server';
 
new Promise((resolve, reject) => {
  const htmlWritable = new HtmlWritable();

  const { pipe, abort } = renderToPipeableStream(renderResult, {
    onAllReady() {
      pipe(htmlWritable);
    },
    onError(error) {
      reject(error);
    },
  });

  htmlWritable.on('finish', () => {
    resolve(htmlWritable.getHtml());
  });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    React 18Bug reports, questions, and general feedback about React 18Status: UnconfirmedA potential issue that we haven't yet confirmed as a bugType: Discussion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions