Treat your users right with Segmented Rendering

Rate this content
Bookmark
Slides

If you think that static rendering is limited to generic and public content that is the same for every user of your website, this talk is for you. Segmented Rendering is a new pattern for the Jamstack that lets you personalize content, statically, without any sort of client-side rendering or per-request Server-Side Rendering. Get the best possible performances for use cases such as theming, internationalization, A/B testing, multi-tenancy, and start treating your users right!

21 min
24 Oct, 2022

Video Summary and Transcription

The Talk discusses the concept of segmented rendering for personalization in web development. It explores different rendering techniques, including server-side rendering, static seed generation, and dynamic rendering. The issue of rich guests and poor customers is addressed through segmented rendering. The implementation of segmented rendering with Next.js involves a lightweight proxy server and URL rewriting. The Talk also highlights the benefits of invisible server-side rendering and suggests a future unified API for server rendering.

Available in Español

1. Introduction

Short description:

Hello everybody and welcome to my talk, Treat your users right with segmented rendering. My name is Eric Burel. I'm the founder of LBKE, a small company in Montpellier, France. I'm a web developer but I'm also a consultant in public funding for research to business. I'm the maintainer of VulcanJS, a framework you might know if you come from the Meteor.js ecosystem and that is now running on Next.js and GraphQL.

Hello everybody and welcome to my talk, Treat your users right with segmented rendering.

First, let me introduce myself. My name is Eric Burel. I'm the founder of LBKE, a small company in Montpellier, France. I'm a web developer but I'm also a consultant in public funding for research to business. I'm the maintainer of VulcanJS, a framework you might know if you come from the Meteor.js ecosystem and that is now running on Next.js and GraphQL. I'm a member of the DevoGraphics Collective created by Sacha Gref who runs the State of GS, CSS and GraphQL surveys. I'm in particular in charge of the survey form where you actually fill the survey and I am teaching Next.js at Human Coders, a teaching company in France. You can meet me on Twitter or on Medium where I publish a few articles on various subjects, namely Next.js and GraphQL.

2. Personalization and Rendering

Short description:

I'm going to talk about personalization and explain what is the segment in segmented rendering. Web personalization includes examples like theming, internationalization, paid versus free content, and A-B testing. Next.js is a framework that offers three ways of rendering applications, including client-side rendering.

I'm going to talk about personalization to explain what is the segment in segmented rendering. So what is web personalization? Let's take an example. Picking a theme is the most basic example and the most visible example of web personalization. Let's say that in my application I have three possible themes fire, water and grass and each theme will change the display of the application. To implement theming, most often I will use a cookie. This is very common for web personalization to store some specific information about the user in a cookie. Why? Because they are automatically sent alongside every request and if they are not HTTP only they are also available to the javascript code. So they are very useful to keep information, to tell who is the user. What's their segment? In which category they belong for instance. So here I could have a cookie named starter with three possible values fire, water and grass.

Okay and depending on the value of course I pick a different theme in the application. But it's not the sole use case. There are many use cases of web personalization. We have this same in use case but also internationalization. It's a case of personalization that we we sometimes forget but when we change the language of an application to adapt the language of the user we are doing what we call personalization. We are optimizing the website and the user experience depending on their characteristics. The language we think they talk or the language they selected in a menu. This is personalization. Having paid versus free content is also personalization especially for instance if you have only the beginning of an article before hitting a pay wall. This is personalization in a sense that unpaid users have a different experience from paid users. Paid users have their content and unpaid users are invited to get a subscription. They have a different experience, a personalized experience, and they belong to different segment guest users and paid users. A-B testing is also a very important use case, maybe more advanced, but if you make a lot of money out of a website you probably have set up already A-B testing because it helps you test new versions of your website incrementally without affecting your whole user database. So most often we have two segments that are actually named buckets in A-B testing environment, A and B, and you have two different of the website A and B depending on the on this segment.

Let's come back at our use case rendering the right thing. Let's talk about Next.js because Next.js is a very interesting framework when it comes to rendering because it embeds three ways of rendering applications. The first one is client-side rendering. This is the most common This is the most common way to render content in modern JavaScript applications, in software as a service, because it's very dynamic. It happens in the user's browser so you can do a lot of computation there. It's just using client-side JavaScript and to get data to fill the content of the page, it will be used to browsers built-in like Fetch or libraries that are themselves built on top of these built-ins like SWR in the Vercell ecosystem.

3. Rendering Techniques

Short description:

Server-side rendering is the polar opposite of client-side rendering. Static seed generation is a middle ground that allows for generating multiple versions of a page based on parameters. Dynamic rendering, such as client-side rendering, allows for real-time updates but requires more computations. Static generation, while not adaptable to individual requests, is faster and can be tempting for personalization.

Server-side rendering is the polar opposite. You are doing everything on the server for each request. This is closer, for instance, to how PHP works. When you do a request it will hit a page that is a template. The server will fetch some data from the database at this point and will fill the template with the right values, and you end up with your rendered page that is then sent as-is to the browser as pure HTML.

And you have static seed generation, which sits in between, which is basically just server-side rendering, but not paired request, but computed at build time. It's similar in a way to just writing HTML. You could just write the page. But of course, it would be quite dumb to write the content directly. So static seed generation lets you do this at scale. You have the same page, and the static seed generator is able to generate multiple versions depending on some parameters you input, like the language, the theme, and so on.

They divide into two categories. The first one would be the dynamic ways to render a content. Client-side rendering and paired-request server-side rendering are dynamic because server-side rendering happens for each request. So the data can be updated every time the user refreshes the browser, at least. Client-side rendering is even more dynamic because it can be interactive, since it operates on the user's browsers. It can do computation any time. It doesn't even have to talk with the server. So most often you have this pattern, this jam-stacked pattern of calling APIs to get new data and rendering everything client-side. This is very jam-stackish way of doing things.

Static seed generation is well static. Because things are computed at build time, they cannot evolve for each request because you don't have the request yet. No one requested your server, you are just building it and deploying your server at this point. But it's faster because things are already computed and stored in a cache, so there is no new computation. The server just has to serve the computed HTML. And what will you use for personalization? You might be tempted to say dynamic patterns because they can adapt to the request because they can happen in the user's browser, so literally on their machine. It's easier to adapt and to personalize for a precise user, of course. However, they are slower. They need more computations. So you also have the choice to use static generation, but how? It's faster, so it's tempting.

4. Segmented Rendering for Rich Customers

Short description:

Using dynamic and slower rendering for personalized content creates a rich guest, poor customer issue. Unpaid visitors and guest users receive faster static renders, while authenticated customers with personalized content experience slower rendering. Segmented rendering addresses this issue by enabling static renders for personalized content.

But how? Again, since it doesn't move, how do you do that? And using systemically the dynamic and slower solution leads to an issue that I call the rich guest, poor customer issue. You will use the faster static renders only for public content, for content that is available to anyone surfing the web. So unpaid visitors, guest users, as well as connected users. And you will use the slower dynamic renders for personalized content. You will do use CPU time from the users, if you do client-side rendering. You will have slower computation on the backend if you do pair requests server-side rendering. So basically your customers that are authenticated, that receive personalized content based on their own personal data, have the poorest pattern, the slowest pattern. They are poor customers, while the guests that provide most often less value on the website because they are not connected, you don't know them, you can target them, they are not customers, they have the best experience. They are rich guests. This is the rich guest, poor customers issue. And segmented rendering is a way to reduce this issue by enabling static renders for personalized content to have rich customers.

5. Personalized Staticness and Proxy Server

Short description:

Let's talk about personalized staticness using segmented rendering patterns. The easiest implementation is to have one URL per segment, one URL per theme choice for users. But it leads to some issues. Users shouldn't be able to tell in which bucket they are. The URL can become long and ugly. To solve this issue, let's introduce a simple, lightweight proxy server.

So let's talk about personalized staticness using segmented rendering patterns. Let's do a first try, let's try to use the URL to personalize the content statically. It's very easy because most static seed generators rely on the URL, be it next.js, or Gatsby, or Astro, and so on. You give them URLs to render, and depending on the parameter, they will fetch the correct data and render the page accordingly. That's how they work.

So it's the easiest implementation, is to have one URL per segment, one URL per theme choice for users. So users that picked the fire theme will have one version, water theme one version, and grass theme one version. But it leads to some issues. First, the user can change the URL. It's okay for a theme, it's okay for a language. It's even a feature in a way, for a language. You can change the language of the page by just changing the URL. But it's a problem if you start doing personalization with paid content. You don't want users to change the URL to suddenly become paid users. You'd rather want them to pay for something. Then the user can see the parameter. Again, not a problem for a language, it's even a good thing for a language because it allows sharing the URL to other people speaking the same language with the language in the URL so they get the right content. But for an A-B test, that's a huge issue. Users shouldn't be able to tell in which bucket they are. Otherwise, you are drastically biasing the A-B test. It leads to a lot of issues and the data are just not valid anymore. So they shouldn't see the parameter in this case. And finally, the URL can become long and ugly. If you have a lot of parameters, you will end up with the language, the dark or light theme, the tenant, the company, the organization the users belong to. If you are doing business to business, it's very common to have multi-tenancy. To have multiple companies using your application with a lot of users per company. You will have the A-B test bucket, which is not good, paid content and so on. You have very long and ugly URLs.

So, to solve this issue, this limitation, let's introduce a new piece in our architecture. Let's introduce a simple, lightweight proxy server.

6. Proxy Server and URL Rewrite

Short description:

The proxy server rewrites the URL based on the segment, making it invisible to the user and protecting it from being changed. The length and appearance of the URL are no longer an issue, and there are advanced patterns to compress parameters if needed.

The role of this proxy server will be to take the HTTP request that hits the server and to re-write the URL, depending on the segment. I insist on the word re-write the URL, and not redirect the URL. A URL re-write is not visible to the end-user, and that's the key difference, because it solves all our issues with the URL at once.

The user cannot see the parameter anymore. The user cannot change the parameter anymore, because it's protected by the server, it's computed server-side. So the user cannot hack it by just changing browser values. And finally, the fact that the URL is long and ugly is not a problem anymore, because the users do not see it anymore. You can reach the limitation of 255 characters for URL, but in practice this will never actually happen. And even then we have more, even more advanced patterns to fix that. It's linked in the resource it's called the Megaparam patterns. Basically, you can encode the parameters to compress them. So there is solution even for this slight limitation.

7. Segmented Rendering and URL Rewriting

Short description:

To solve our issue, we convert the cookie into a URL parameter compatible with existing frameworks. This is called segmented rendering, where each variation has a unique URL. For example, for internationalization, the accept language header can be used to rewrite the URL to the correct language, eliminating the need for an explicit language parameter. Users can change the language using an invisible cookie instead of a visible URL parameter.

So to solve our issue, we have an HTTP request with the cookie fire and we turn that into a URL parameter fire, which is compatible with how existing frameworks work because Gatsby, NEFGS will be able to statically render content as long as the URL for each variation is unique. This is what we call segmented rendering. This is a recipe with two ingredients having one URL per segment. This is just how static rendering works. If it generates multiple variations of your website statically, you already do this but the trick is to use a tiny URL rewriting server to redirect to the right URL depending on other parameters of the request like the cookies or the headers. If I take another example with internationalization you could use the accept language header and rewrite the URL to the right language. This would remove the need from having an explicit language parameter. You still need a way for users to change the language but you could do that using a cookie that is invisible instead of using a URL parameter which is visible and in some scenarios might be ugly.

8. Implementation with Next.js

Short description:

Let's take a look at an implementation with Next.js. Our application uses segmented rendering to allow users to pick a theme. The theme is stored in a cookie, providing personalization without altering the URL. The page is statically rendered with the chosen theme, and the server response confirms the correct theme. The implementation involves static seed generation and incremental static regeneration for flexibility. The middleware, a lightweight proxy server, reads the theme cookie and writes the URL. This achieves segmented rendering without the need for a root parameter.

Okay so this might sound a bit abstract. So now let's take a look at an implementation with Next.js which is very interesting because it allows Next.js embeds the concept of edge middlewares that are exactly that. The proxy server that we need to implement segmented rendering. They provide that out of the box.

So here is our application using segmented rendering. It's a Next.js application that lets me pick a theme fire, water or grass. Okay so let's pick the fire theme. You will see that it changes the color as expected. The interesting part is that it doesn't alter the url. First, so if I go to application and check the cookies for this application I will see that I'm relaying on the theme cookie name fire instead of using a root parameter I'm using a cookie which is the right way to do personalization in many scenarios. Second interesting fact is that if I reload the page I will get the themed version already. Of course this is all statically rendered so for instance if I go to the network and I check the response of the server for the html request I will see my content with the right theme. So here I've not configured the the CSS for server-side rendering but I can see the fire theme in the html already so I'm indeed using static rendering. This is computed in advanced server-side there is no client-side computation happening.

Regarding the implementation the first piece is just a page with static seed generation as you would find in any Next.js application using get static path, get static props as usual. I generate different version of the page depending on the theme parameter. Notice that I'm using incremental static regeneration which is just a pattern in Next to understand the Next to handle the case where I have a lot of themes. For instance, here I'm not pre-rendering the green starter because maybe this is less requested by people and I don't want to have a very long build time so it will be computed only on the first request. So we have a lot of flexibility with this approach. And then of course I render my page based on this parameter. This is very usual if you use Next.js or any other static rendering framework, you will be used to this approach. But the most important part is the middleware. This is my proxy server. And when I mean tiny and lightweight, I'm not joking. It's 25 lines with a lot of commands. What it does, reads the cookies. If it's a valid theme, it will write the URL. Okay. As simple as that. This is how I get segmented rendering, so static rendering with personalization without using a root parameter.

9. Invisible Server-Side Rendering and the Future

Short description:

This part discusses the security and benefits of invisible server-side rendering for personalized themes. It also mentions the implementation example and the use of segmented rendering at the edge. The conclusion highlights the importance of caching in server-side rendering and suggests a future unified API for server rendering.

This is invisible to the user and this is secure because it's happening server-side. I can't let the user pick a theme that does not exist, for instance. They can only select fire, water, grass, or none. Otherwise, I throw an error. This is secure. It's great for paid content, A-B test, for instance.

Finally, just a detail, but that's optional, I've added some logic to switch the theme based on a cookie using an API root. So, I'm using the set cookie HTTP header, but you could do the same client-side, of course.

Let's get back to my slides. So, now you have an example of the implementation, and in Vercel, you might have a different wording. They won't call that segmented rendering. They will call that edge personalization. And it's actually the Vercel translation of this pattern. This is the same thing, except that Vercel is allowing you to have segmented rendering at the edge using its edge network. But it's basically the same idea.

Short conclusion. What's the future of server-side rendering? I think the future of server-side rendering is understanding that it's all about caching. Static is server-side rendering cached at build time. Per request, server-side rendering is just a cache miss in the same pattern. The cache key is not just the URL, but the full request. This is the idea behind segmented rendering, to use the request and not just the URL. And the value is of course the rendered HTML, or the data. It depends on the pattern. Gatsby deferred static rendering, for instance, is untying both and Next.js is always considering them as a whole. They are very tightly related in Next, but either way, that's the cache value. So my take is that in the future, we will have a unified API for server rendering that encompasses static PairRequest and everything in between. And until that, we have segmented rendering.

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 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
Do you have a large product built by many teams? Are you struggling to release often? Did your frontend turn into a massive unmaintainable monolith? If, like me, you’ve answered yes to any of those questions, this talk is for you! I’ll show you exactly how you can build a micro frontend architecture with Remix to solve those challenges.
React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Too much JavaScript is getting you down? New frameworks promising no JavaScript look interesting, but you have an existing React application to maintain. What if Qwik React is your answer for faster applications startup and better user experience? Qwik React allows you to easily turn your React application into a collection of islands, which can be SSRed and delayed hydrated, and in some instances, hydration skipped altogether. And all of this in an incremental way without a rewrite.

Workshops on related topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Featured Workshop
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn