Intermediate React

Intermediate React renderToNodeStream


This course has been updated! We now recommend you take the Intermediate React, v5 course.

Check out a free preview of the full Intermediate React course:
The "renderToNodeStream" Lesson is part of the full, Intermediate React course featured in this preview video. Here's what you'd learn in this lesson:

Increase performance of server side rendering in Node.js by streaming out the markup to the client as soon as it's available using renderToNodeStream.

Get Unlimited Access Now

Transcript from the "renderToNodeStream" Lesson

>> Brian Holt: So I've cut a commit here. And so if you're interested in that, you can go grab the commit right there. This is in the branch SSR. But I want to take this one step further because React server-side rendering got better with 16.0, I guess, yeah, 16.0. Right now, this is a pretty small application so this would be good for what we're doing.

[00:00:23] But imagine we have a super, super long document that takes a while to render. That could be a problem with this because this is gonna really slow down as it's doing all that server-side rendering, particularly when some of it's already done upfront. So would it be great if we could stream the markup to someone?

[00:00:40] If they immediately call the page and I just immediately flush something out to them so they can see something, right? That would be pretty cool. With React 16, that became possible with a method called renderToNodeStream. So I want you to go back and open your app.js. I want you to change instead, sorry, not app.js, but server.js.

[00:01:04] Rather than say renderToString, I want you to say renderToNodeStream, okay?
>> Brian Holt: So we're gonna reorganize this a little bit. So rather than just doing one res.send down here, we're going to res.send a couple of times. So the very first thing when someone, in fact, I can just get rid of that right there.

[00:01:30] The first thing that I'm gonna do when someone makes a request, I'm going to immediately flush out the header. So I'm gonna say res.write(parts

[0]). So the first thing they're gonna get all the CSS, they're gonna get all the title of the document. And this is gonna be a big performance one because immediately there gonna start loading CSS.

[00:01:53] Whereas before they had to wait for the entire document to finish before they start downloading CSS. While you're still finishing your server side rendering, guess what? They're downloading your CSS. So you're just getting ahead of the curve here a little bit.
>> Brian Holt: Okay? After that then I'm gonna do the res.markup stuff, or the reactMarkup stuff.

[00:02:14] Then I'm gonna do const stream = renderToNodeStream(reactMarkup). Okay, so this is going to be what's called a NodeStream which I'm not gonna get too much into. It's a primitive type for node that you can have data returns multiple times basically, right? It's gonna be a stream of oncoming data.

[00:02:38] And I'm gonna say stream.on, or sorry, stream.pipe first, stream.pipe(res, [ end: false ]). So what this is gonna do is it's gonna take stream as it has more data coming back from React rendering. It's gonna just pipe that into res, right? Pipe in the sense of bash, right?

[00:02:59] It's like connecting two pipes together. That the stream pipe is now connected to the res pipe, right? This end: false thing is once this stream finishes, I'm not done yet, cuz I still have to write the footer, right? parts[1] up here. Here I'm gonna say stream.on("end") so once it is finished, run this function.

>> Brian Holt: What I want it to do is I want it to res.write(parts[1]). And then up here, I'll just move this res.end in here. So once this has ended, once I've written parts[1], then I want to finish, right? And I'll close the stream.
>> Brian Holt: And everything else stays the same.

>> Brian Holt: So let's go start and stop our server again. Keep in mind this is not live reloading. So every time that you make any sort of modification to this, you have to stop and start your server. If you wanna have that kind of live reload, you're gonna use something called node daemon.

[00:04:07] I won't show you how to do it but just know that it's out there.
>> Brian Holt: So now if I refresh this page, honestly largely, you're not gonna to see much of a difference, right, because this is such a small application. But I wanted to show you how you do streams, right, so you can have multiple kind of chunks being loaded at the same time.

[00:04:26] This will be much better if you have a large application.
>> Brian Holt: Yeah, even this won't really see cuz the chunks return so quickly that it's hard to really see that happening. But it's a huge, huge win.
>> Brian Holt: Any questions about this?
>> Brian Holt: This is always something you wanna measure, how much this is benefitting you, because obviously there are trade offs.

[00:05:01] Usually, server-side rendering is a win, but it is not always a win. In this particular application, where this pedadoctor app is so small, it's probably a net lost. It's probably faster to just download all the markup and download all the job descript and have them react to application bootstrap client-side, so it depends.

>> Brian Holt: Great, that's service side rendering. That's really all there is to it, so,
>> Brian Holt: Something you can definitely do.