Dear Client, I'm Leaving You

Rate this content
Bookmark

With React Server Components and React’s new suspense SSR capabilities, we get an paradigm shift in the world of client/server side rendering. The pendulum that started in plain HTML pages, quickly swinged to all-client-rendering, is now returning to the server side. Emerging frameworks like Next.js and Remix usher a new era of web development, one where SSR is a first class citizen. In this talk we deep dive into those React features, talk about the state of the art practices regarding server rendering, and maybe get a glimpse into the exciting future of front-back-full-stack relationships.

21 min
21 Jun, 2022

Video Summary and Transcription

Liad Yosef discusses the importance and evolution of server-side rendering, highlighting its benefits such as improved performance and SEO. He explores different rendering strategies and the challenges of hydration in React. He introduces SuspenseSSL in React 18 as a solution for fetching data in advance and selectively hydrating components. He also mentions React Server Component as a game changer for reducing bundle size in rendering with React.

Available in Español

1. Introduction to Server-Side Rendering

Short description:

In this part, Liad Yosef introduces himself and the topic of the talk, which is server-side rendering. He mentions the importance of discussing this topic and refers to a quote by Abraham Lincoln. He also mentions that the talk will focus on server-side rendering in React.

Hi. Hi, everyone. Thank you for attending my talk. I'm Liad Yosef. My talk is called Dear Client, I'm Leaving You. We're going to talk a little bit about server-side rendering, server-side rendering, and everything in between.

So I'm Liad Yosef. I'm the lead front-end architect in Douda. I'm a web enthusiast, and in my free time, I'm also an analog astronaut. I have the privilege of going to analog missions around the world, I really like space. So with this in mind, we will turn our talk into somewhat of a dark mode talk, and it will be a space theme.

So you might ask yourself, why do we need to talk about server-side rendering? Abraham Lincoln once said that if I had eight hours to chop down a tree, I'd spend six sharpening my axe, and Rick Sanchez added that the universe is much more complicated than you think. So be prepared for a 20-minute adventure on the rabbit hole of server-side rendering, and how do we approach it in React?

2. Understanding Server-Side Rendering

Short description:

In this part, Liad Yosef discusses the concept of server-side rendering and its evolution over time. He explains the difference between classic server rendering, client-server rendering, and new server-side rendering. Liad highlights the reasons for using server-side rendering, such as improved performance, better SEO, and addressing issues with client-side rendering. He also mentions the importance of considering performance criteria like cumulative layout shift and large contentful paint. Additionally, he references a talk by Rich Harris on the impact of single-page applications on the web.

It's not like we're watching Dan Abramov on Netflix. So I'll frame my talk a little bit like Netflix. There are a lot of topics to discuss. You can either choose performance or hooks or money heist, a web three or a grid game, but I will focus about server walls.

Server walls, that's something that we need to learn. We need to understand in order to really understand the client-server relationship. And we will start with a small history one-on-one on the client-server walls. So when we talk about classic server rendering, what are we talking about? So in classic server rendering, the product that was common about 15 or 20 years ago, the server generates a display markup and the client runs the interaction logic. You can think about PHP or JSP or everything else that you are familiar with. So in classic server rendering, the browser asks for the server to assemble the page. The server assembles the page on the server side, sending the flat markup into the client and the client gets the markup. That's the classical server rendering. And if they want to make their markup interactive, they just ask the server to send the milestone, the JavaScript, to make them useful. That's classic server rendering.

In client-server rendering, that's a paradigm we started working with about 10 years ago, the client is in charge of generating the display markup and the interaction logic like in React. So, the client asks to assemble the page and the server just sends an empty container and then it's the client's responsibility to ask for React or the JavaScript code to render it themselves. React renders the markup and if there's something else that the client wants, they can ask for the server for another JavaScript code to render the missing part. That's client side rendering. In the new server side rendering, which is the paradigm that we started to work with about two or three or four years ago the server is in charge to generating the display markup and the client is in charge of running the interaction logic. Wait, what? I mean, we've just come full circle from the PHP of 20 years ago to the server side rendering of today. Well, you need to remember that React is a templating language. So you can use it in the server in order to template as well. You might ask yourself why? What is the reason of doing server side rendering? Well, in the past, when we had slow network speeds and slow devices, we had to do everything on the server, right? Because the client wasn't strong enough or powerful enough to render it. As devices became stronger and the customers wanted more complex apps, we shifted rendering into the client. But now as the networks become really fast and there's a lot of complex code that is being sent to the client and our loading standards have become higher, so we want things to be loaded much faster, we have to shift the rendering back to the server. If we talk about performance, those are two criteria that Google checks in their Core Web Vitals. Then cumulative layout shift actually checks what happens when the client renders the markup, but something pops out in between because the client is rendering it incrementally, and then you click on something that you didn't want to click. Or large contentful paint, how much time does it take the client to fetch the data in order to render something, which is a problem in clients' underrendering world. SEO is also a problem, because when Google tries to index our page, they go into the server, they ask for the page, and if the server returns just an empty container, Google doesn't know how to index our page. There's a really good talk by Rich Harris called, Single Page Application Ruined the Web, and generally there's a really good talk in the Twitter sphere, or in the web, about Single Page Application versus Multipage Application, where some people say that multipage applications fall short because they don't give the experience that we want, and other people say that single-page applications, because they load really slow, don't give the performance that we want.

3. Understanding Rendering Strategies and Spectrum

Short description:

There's a debate about single-page applications versus multipage applications. Rendering involves who builds the markup, how it becomes interactive, when it's built, and where it's served from. Static rendering provides the same page for everyone, easily cached but not personalized. Client-side rendering allows for personalization but can't be cached and has slow first loads. Incremental static regeneration generates some pages on demand. Real-time server-side rendering is used for personal content. React level components are suitable for web apps with static and dynamic parts. Classic static rendering relies on the cache for serving pages. Incremental static rendering generates variations in the cache. The server is still required, and caching can be triggered by the cache itself.

There's a really good talk by Rich Harris called, Single Page Application Ruined the Web, and generally there's a really good talk in the Twitter sphere, or in the web, about Single Page Application versus Multipage Application, where some people say that multipage applications fall short because they don't give the experience that we want, and other people say that single-page applications, because they load really slow, don't give the performance that we want. That's an ongoing debate.

But in order to understand a little bit what we are talking about, we need to understand what we are talking about when we talk about rendering. So, rendering 101, we talk about who builds the markup. It can be either the client, the server, or the edge in between. How does it become interactive? Is it the client that makes it interactive? Or is it the JavaScript code that makes it interactive? Is it the native browser functions? Or is it the React that makes it interactive? When is it being built? Is it being built in build time or in runtime? And, of course, where is it served from? Is it being served from some sort of an edge network, or a cache, or the server itself?

So, if we think about a simple blog, for example, which is very static, then we know that it is being built in build time, it is being interactive. We're using JavaScript code. The server is building it, and it's being served from the cache, right? Because you don't need to rebuild it in runtime. But if you have a complex web app, that's something that the client is building, probably using React or some other frameworks, and it requires server. It requires a runtime server in order to operate. So, if we think about those two parts, those two edges of you have server-side rendering for very static, simple pages, on the one hand, and you have client-side rendering for very complex web apps, on the other hand, you can put them on a spectrum, because those are not the only two options that we have. So, in static rendering, which is the server-side rendering in build time, you're getting the same page for everyone, and it can be easily cached, but it cannot be personalized. And you cannot have variants, because you need to build everything in build time, and it requires a build for every update, whereas in the client-side app, which is the most dynamic, it can be easily personalized because you do it on demand in the request, but it cannot be cached, and it has slow first loads and slow data fetches, because you have to go to the server for everything, but it has fast in-app responsiveness. But we need to remember, this is a spectrum, so, if I want to build a listing page, and I want for every page in the listing to be different, because I have 10,000 properties that I want to list, then I can use something that's called incremental static regeneration, which is not just generating everything on build time, but generating some of them in build time, and some on demand. If I want to build something that is more personal, like my bookings, or my account, or things that need my data, need my cookies in order to present, then I would have to go with real-time server-side rendering, because I can't cache anything, and, on the other hand, if I want to build a web app, but most of the parts of the web app are static, and only parts are dynamic, I would go with React level components. We will talk about all these strategies.

So, when we talk about SSL strategies, or the multiverse of madness, we need to remember that when we speak about static rendering, we no longer talk about only the client and the server. We need to put something in between, which is the edge network, or the cache, and then we can discuss about the relations between the client, the edge, and the server. In classic static rendering, which is like we saw, the blog pages, the server generates the page on build time, and it sends the page to the cache, to the edge network, and then it goes out of the picture. We don't need the server anymore. It just generated the page, and that's it. The client asks the cache or the edge for the page, and it gets the page, it gets the blog post, and it's important to understand. It's important to notice that all of the clients will get the same page because they all ask it from the cache. Like we said, the pages are easily cached, and they do not require a server, and they have great performance, but they do need rebuild for every update, and there's a problem with data fetching.

In incremental static rendering, the server builds the page, sends it to the cache to be cached, but it also builds a lot of variations, a lot of other variations in the cache, and when the client asks the cache for a page, they get the page, and another client can ask for another page, and they will get another page, but if a third client asks for a page that does not exist on the cache or in the edge network, then it goes directly to the server. The server generates it in real time and sends it to the cache, caches it, and then the client talks to the cache and gets this page. It is like the best of both worlds, but you do still need a server. It can also be triggered by the cache. You can do an invalidation time. For example, if you have a page that needs to be revalidated or refreshed every couple of minutes, then when the client asks the cache for the page, the cache can say this is the page that you want, and the next client, the cache can say, hey, the page is stale, asking the server to regenerate it, while at the same time serving the stale page to the client, and then the server regenerates a new page, replaces it in the cache, and then the next client will get the updated page, which is pretty nice.

4. Rendering Strategies and Hydration

Short description:

Incremental static rendering allows for caching and reduces build times for multiple pages, but cannot reflect user-specific data. Full server rendering provides highly personalized content and unique pages without a build process, but has a long response time. Edge rendering combines the benefits of rendering and the edge network, allowing for fast and streamed HTML. Hydration, the process of making the markup interactive, is a challenge as it requires sending all the code to the client and cannot be partially hydrated. React is working on solutions such as suspense and other components.

That can also be triggered from the server. So it can be triggered when the server gets new data, it can say, hey, it's been a few minutes since I updated the cache, it can generate a new page or an updated page, replace it in the cache, and then the next client that will ask it from the cache will get the updated version, which is nice.

So in incremental static rendering, it is easily cached, it's very cache heavy, you still rely on cache, it reduces build times for multiple pages, so if you have thousands of blog posts, you don't have to build all of them in advance, but it does require a server, and it cannot reflect user-specific data, because you don't really go to the server and generate a unique page, and the trips to the server are long.

Full server rendering, that's something that's what we call server-side rendering, we have to remember that the cache is no longer in the equation, the client speaks directly to the server, so the client can ask a highly personalized page, for example, account details, my account or my listings, and the server will build it, and it will send to the client something that's very unique to that client. And if another client will ask the server for the page, the server will build something else completely, because that's a different client, a different customer, and they will send it to them.

So, in full server rendering, we get a very highly personalized content and unique pages, and we don't need a build process, which is important, but it does require a server, and we still have the long response time from the server. Why the long response time? Because if we look at the server code, for example, we can see that the line that is relevant here is a render to string, and this line is synchronous, so we need to render everything before we can send the page, and that's a problem. And we will discuss some ways to solve it soon.

And there are voices that say that if your server-side rendering takes more than 200 milliseconds, maybe it's better to do client-side rendering instead.

And now the new thing that everyone is talking about is edge rendering or using the edge network in order to render, and that's like having the best of both worlds, because if we have the edge network that is being spread around the globe, we can use it to render the pages. We don't have to do drifts to the server. So if we just join the rendering and the edge network, we can have something like this. We can have the edge around the world, the client asks for a person-like page from the edge network. The edge network builds it and returns it in real time. But since the edge, it's like a CDN, so it's spread all across the globe, you get the edge point that is closest to the client, which makes it fast. So edge rendering will allow streaming, because now that you have fast times and short times between the edge and the client, you can stream HTML to the client so the client can see parts of the HTML as they are being rendered. It does require an edge network and Next supports it, Remix is going to support it, Netlify has Netlify edge functions, which is pretty awesome. So that's something that you want to take a look at.

And now let's talk about our nemesis, our enemy, hydration. So hydration is actually the process that's happening in the client after they get the markup. And that's a problem, because if you think about it, who is giving life to the markup? It can be either the browser that is using native browser interactions like form submits and drop downs and things that the browser know how to handle. That remix is heavily relying on this. Or it can be JavaScript, right? So the browser can ask for the server to send some JavaScript code in order to make the markup alive or interactive. Or it can be React. But React does hydration, meaning that it builds all the markup in the server and then the server sends it to the client and then the client has to ask React again in order to rebuild the markup, which is pretty wasteful, rebuild the markup. And only then it adds the interaction logic, right? So this is a React based hydration and in React, we need to send to the client both the rendering code and the interaction code, which makes you wonder if the only code that we need is this is the interaction code. Why do we need to send all of this to the client? So hydration is becoming a problem because you have to send all the code to the client and because you can't really partially hydrate. You have to wait for all the code to get to the client until you can hydrate. And you can read the Steve Sower, he has a really good blog post on that. And React is trying to solve it with suspense as a start and React's other components.

5. Using SuspenseSSL for Server-Side Rendering

Short description:

So a short primer about suspense. Our problem with SSR is that we need to fetch all the data in advance in the server, load all the JavaScript before the hydration, and then hydrate everything before you can interact with it. If you want to build a website of mentorship to the Avengers, you have to fetch everything in advance, which is hard. But SuspenseSSL comes to our rescue in React 18. React introduced streaming HTML and SelectiveHydration, allowing us to stream HTML to the client and hydrate selectively. Instead of using render to string in the server and hydrate in the client, we can use rent to pipe of the stream and hydrate root in the client. The same suspense code will be rendered in the server and sent to the client. React will hydrate whatever it can in the client, and when the reviews are ready, the server will push a script to replace them in the markup.

So a short primer about suspense. If we want to render something lazily, like here, we want to render mouse only if Elon Musk is present. We wrap it in suspense and then we get a nice spinner if you want. And only when Elon Musk arrives, we can render mouse. So this is the idea of suspense.

And our problem with SSR, like we said, is that we need to fetch all the data in advance in the server, load all the JavaScript before the hydration and then hydrate everything before you can interact with it. So it's like a waterfall. Server fetches all data, then the server renders the entire HTML and sends it to the client. Then the client loads the entire JavaScript code, then it needs to hydrate the entire app. So that's a problem.

So if you want to build a website of mentorship to the Avengers and you call it mentor and for example, everyone can select a mentor of their choosing, and you have the mentor page, which is that you have the image and the reviews on the mentor and the name of the mentor, right? So you build it in React. It's pretty simple. You have the name, the image, the description, and the reviews. And let's say that you want—so if the server renders it, it's really simple. So the server just renders it into markup, sending it to the client, and then React does its magic in the client and it becomes interactive and that's amazing. But let's say that you want the mentor image and the mentor reviews to be lazily loaded. Maybe it takes a lot of time to pull the reviews from the third-party data source. So you want to wrap it, let's say, in suspense, right? You would wrap it in suspense with a fallback. But then you have a problem with the SSL, because React will render it in the server, but it doesn't know what to do with the suspense part. It doesn't know, because it's not there, so it will send it to the client, but React in the client doesn't really know what to do. So that's a problem, because you have to fetch everything in advance. And this is the part where SSL is becoming hard. That's why we didn't really utilize SSL in large scale until a few years ago, because it's hard. But SuspenseSSL comes to our rescue in React 18. React introduced streaming HTML, the ability to stream HTML to the client, and SelectiveHydration, the ability to hydrate selectively parts of the clients. So instead of using render to string in the server and hydrate in the client, we can just do rent to pipe of the stream and hydrate root in the client. And then the same suspense code will be rendered in the server with the loading with the spinner and being sent to the client. Then React will hydrate whatever it can in the client. And only when the reviews will be ready, the server will push to the client some sort of a script that said, hey, the reviews are ready. Just replace them in the markup, which is pretty amazing.

6. React Server Component and Bundle Reduction

Short description:

React Server Component is a game changer for rendering with React. It allows you to define parts of a page as server components, which can go to the database and bundle dependencies without being shipped to the client. By defining only the interactive part as a client component, the bundle size can be reduced by 90%. Check out Dana Bramov's talk and the server component RFC for more information.

And it also knows to do SelectiveHydration. So if several parts of the page are being hydrated and the user clicks on one of them, then React automatically prioritize this part to be hydrated and they know to replay the clicks on this part, which is pretty awesome. React Server Component is also a game changer. It basically means, I won't dive into it because there was another talk on that, but it basically means that if you have a page, that most of the page is statically rendered, you don't need a lot of interaction code, you don't need React, but you want to render it with React. Let's, for example, just the mentor rating is something that you want to be interactive. Then you can just define some part of the page as server components, and those parts can go to the database and they can bundle a lot of dependencies, but none of them will be shipped to the client. So if you just define parts as server components and only your interactive part you define as client component, then only this client component will be bundled and sent to the browser and that can reduce bundle in 90%, which is pretty amazing. There's a good talk of Dana Bramov on that, I recommend you to read server component RFC, it's very informative.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2023React Advanced Conference 2023
27 min
Simplifying Server Components
Server Components are arguably the biggest change to React since its initial release but many of us in the community have struggled to get a handle on them. In this talk we'll try to break down the different moving parts so that you have a good understanding of what's going on under the hood, and explore the line between React and the frameworks that are built upon it.
React Day Berlin 2023React Day Berlin 2023
21 min
Exploring React Server Component Fundamentals
I've been developing a minimalistic framework for React Server Components (RSC). This talk will share my journey to deeply understand RSC from a technical perspective. I'll demonstrate how RSC features operate at a low level and provide insights into what RSC offers at its core. By the end, you should have a stronger mental model of React Server Components fundamentals.
React Summit 2023React Summit 2023
26 min
Server Components: The Epic Tale of Rendering UX
Server components, introduced in React v18 end these shortcomings, enabling rendering React components fully on the server, into an intermediate abstraction format without needing to add to the JavaScript bundle. This talk aims to cover the following points:1. A fun story of how we needed CSR and how SSR started to take its place2. What are server components and what benefits did they bring like 0 javascript bundle size3. Demo of a simple app using client-side rendering, SSR, and server components and analyzing the performance gains and understanding when to use what4. My take on how rendering UI will change with this approach
React Advanced Conference 2023React Advanced Conference 2023
28 min
A Practical Guide for Migrating to Server Components
Server Components are the hot new thing, but so far much of the discourse around them has been abstract. Let's change that. This talk will focus on the practical side of things, providing a roadmap to navigate the migration journey. Starting from an app using the older Next.js pages router and React Query, we’ll break this journey down into a set of actionable, incremental steps, stopping only when we have something shippable that’s clearly superior to what we began with. We’ll also discuss next steps and strategies for gradually embracing more aspects of this transformative paradigm.

Workshops on related topic

JSNation 2023JSNation 2023
174 min
Developing Dynamic Blogs with SvelteKit & Storyblok: A Hands-on Workshop
Featured WorkshopFree
This SvelteKit workshop explores the integration of 3rd party services, such as Storyblok, in a SvelteKit project. Participants will learn how to create a SvelteKit project, leverage Svelte components, and connect to external APIs. The workshop covers important concepts including SSR, CSR, static site generation, and deploying the application using adapters. By the end of the workshop, attendees will have a solid understanding of building SvelteKit applications with API integrations and be prepared for deployment.
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
React Advanced Conference 2023React Advanced Conference 2023
153 min
React Server Components Unleashed: A Deep Dive into Next-Gen Web Development
Workshop
Get ready to supercharge your web development skills with React Server Components! In this immersive, 3-hour workshop, we'll unlock the full potential of this revolutionary technology and explore how it's transforming the way developers build lightning-fast, efficient web applications.
Join us as we delve into the exciting world of React Server Components, which seamlessly blend server-side rendering with client-side interactivity for unparalleled performance and user experience. You'll gain hands-on experience through practical exercises, real-world examples, and expert guidance on how to harness the power of Server Components in your own projects.
Throughout the workshop, we'll cover essential topics, including:
- Understanding the differences between Server and Client Components- Implementing Server Components to optimize data fetching and reduce JavaScript bundle size- Integrating Server and Client Components for a seamless user experience- Strategies for effectively passing data between components and managing state- Tips and best practices for maximizing the performance benefits of React Server Components
Workshop level: 
No matter your current level of React expertise, this workshop will equip you with the knowledge and tools to take your web development game to new heights. Don't miss this opportunity to stay ahead of the curve and master the cutting-edge technology that's changing the face of web development. Sign up now and unleash the full power of React Server Components!
React Advanced Conference 2021React Advanced Conference 2021
170 min
Build a Custom Storefront on Shopify with Hydrogen
Workshop
Hydrogen is an opinionated React framework and SDK for building fast, custom storefronts powered Shopify. Hydrogen embraces React Server Components and makes use of Vite and Tailwind CSS. In this workshop participants will get a first look at Hydrogen, learn how and when to use it, all while building a fully functional custom storefront with the Hydrogen team themselves.
React Advanced Conference 2022React Advanced Conference 2022
81 min
Build a Product Page with Shopify’s Hydrogen Framework
WorkshopFree
Get hands on with Hydrogen, a React-based framework for building headless storefronts. Hydrogen is built for Shopify commerce with all the features you need for a production-ready storefront. It provides a quick start, build-fast environment so you can focus on the fun stuff - building unique commerce experiences. In this workshop we’ll scaffold a new storefront and rapidly build a product page. We’ll cover how to get started, file-based routing, fetching data from the Storefront API, Hydrogen’s built-in components and how to apply styling with Tailwind.You will know:- Get started with the hello-world template on StackBlitz- File-based routing to create a /products/example route- Dynamic routing /products/:handle- Hit the Storefront API with GraphQL- Move the query into the Hydrogen app- Update the query to fetch a product by handle- Display title, price, image & description.- Tailwind styling- Variant picker and buy now button- Bonus if there’s time: Collections page
Prerequisites: - A Chromium-based browser (StackBlitz)- Ideally experience with React. A general web development background would be fine.