Next.js: Reshaping Web App Architecture for Performance Excellence

Rate this content
Bookmark

Are you struggling to achieve optimal performance in your web applications? Are you unsure about how to effectively manage your application's routes while ensuring maximum security for your sensitive data? These are the most recent problems we encountered at l’Oréal Tech Accelerator where our users used to wait in front of empty white screens long before getting the needed information. After extensive research and deliberation, we looked at Next.js as a potential solution to our woes. However, adopting Next.js presented us with a new set of challenges. We had to rethink our architecture and determine the best approach for integrating the frontend, backend, and our core backend systems. In this talk we will discuss in more details the obstacles we faced and the innovative solutions we implemented to overcome them.

Mia NASR KHNEISSER
Mia NASR KHNEISSER
9 min
18 Jun, 2024

Comments

Sign in or register to post your comment.

Video Summary and Transcription

This Talk discusses how Next.js was used to reshape web app architecture for performance excellence. Next.js allows for server-side rendering (SSR) and client-side rendering (CSR), improving performance and user experience. The implementation of Next.js on the application resulted in faster initial page loads, reduced white screen time, and improved loading states. It is important to use the different rendering options correctly to maximize performance.

1. Introduction to Next.js and Web App Architecture

Short description:

I am a full-stack developer at L'Oreal Tech Accelerator, and today I will discuss how we reshaped our web app architecture using Next.js for performance excellence. Next.js allows us to render code either on the server or client-side, improving performance and user experience. We are moving from a single page application to Next.js, which enables us to have an index.html and bundled.js file per page, reducing the amount of unnecessary data on each page. Client-side rendering reduces server load and simplifies backend logic, but it has a slower initial page load. Server-side rendering fills the HTML file with data, but hydration is required for interactivity.

Hello, my name is Myrna Sochnaeser and I'm a lead full-stack developer at L'Oreal Tech Accelerator. Tech Accelerator is an internal department dedicated to driving digital innovation at L'Oreal. We design apps to help L'Oreal staff be more productive.

Today we are going to see how we reshaped our web app architecture for performance excellence and why we decided to use Next.js. At L'Oreal, there are some factors that let us define if we have a good application, like performance, accessibility, security, etc. But today we're going to focus on performance which indirectly also lets us improve our user experience.

At Tech Accelerator, we have an architecture that all our applications rely on. Our browser will try to fetch the data or the information, the files it needs from the CDN. If you do not succeed, you will go get them from the two applications hosted on App Engine. Our backend containing all our endpoints is hosted on CloudRAM and the data is hosted on Cloud SQL. We will try to replace the two applications hosted on App Engine with Next.js and have only one application.

Let's refresh our memory while checking the different renderings we can do with Next.js. Next.js is a framework that lets us create a web application where parts of our code can be rendered either on the server or on the client. This is why we talk about client-side rendering or pre-rendered on the server. And even the pre-rendered on the server is divided into many types like server-side rendering or static-side generation or others. We at first had a single page application where we needed to download one HTML file and one big JS file for all the applications. The HTML file was almost empty and the bundled contained all the information needed. But with Next.js, we will have an index.html in the chunk or bundled.js file per page. And these files will only contain the necessary to render this specific page we are at.

How does the client-side rendering work? After building our front end, we will get two files, the index.html and the bundled.js that was stored into the CDN. Once we try to access our application, the browser will go get the index.html from the CDN and then we will download, the browser will download the JS file and execute it. And once the execution is done, the web page will be visible to the user. But we will still need to go fetch the data from the server to fit the components with the correct data and remove the loading state. So in resume, we will have a white page until we download and execute the bundled.js and the loading page until we fetch the data that we need.

With the client-side rendering, we reduce the server load as the server only needs to provide the initial HTML and JavaScript file and to also simplify the backend logic because the server will primarily act as a data API leading to a cleaner and simpler backend codebase. But on the other hand, we have a slower initial page load since the browser needs to download and execute the JavaScript before rendering the page or displaying anything.

As for the server-side rendering, the browser will get the HTML file from the server. The HTML file will be filled with the correct data. We can directly see the components filled with the correct data on the browser, but they will not be hydrated. The interaction with buttons with links won't work until we fetch and download the JS file from the CDN.

2. Improving Performance with Next.js

Short description:

With SSR, we get faster initial page loads and better performance for low-end devices or slow internet connections. However, it increases server load and reduces interactivity. Static site generation is ideal for providing faster page loads and handling static content. Next.js streamlines the process, improving the initial loading state and user experience. We implemented this on our application, reducing white screen time and loading states. Next.js offers different rendering options, but it's crucial to use them correctly to maximize performance.

We can see that the white page block is reduced and we can directly see something on the web app. So with SSR, we have a faster initial page load and we have a better performance for users on low-end devices or a slow internet connection since most of the rendering process is handled by the server. But on the other hand, we increase the server load especially when dealing with a large number of simultaneous requests, impacting server response times. And we reduce interactivity as additional requests may be needed to update the page content. So SSR is perfect for content websites.

The static site generation is like server-side rendering, but with a small difference that both index.html and bundle.js are created on the build of the application and stored into the CDN. So we display an interactive page very fast. You should use static site generation with Next.js when you want to provide faster page loads and upload pages with heavy content or content that will never change, that are static. Like for example for blogs, for documentation, for portfolios, etc.

This being said, I'm going to give you some context on the application we want to improve in terms of performance. The application is a single page application and we have three types of pages. We have the homepage that is the same for all users and that is static, a page to visualize the data, and a page to create data based on a preset configuration and API algorithm. The application is used by 40 users in six different countries and we have a little bit more than six gigabytes of data. On this application the user has approximately a two-second white page. This is due to the fact that in order for the web app to be visible and actable, the browser needs to download the JS file and execute React. But since the JS file is big, the download and execution of the file took a little bit of time. Once the user started seeing something on the web app, it was the loading state for a certain period of time depending on the page he was looking at.

The solution for us was Next.js. Next.js streamlines the process of dividing the index.html and the bundle.js file into multiple ones per page, providing automatic code splitting. This approach helps improve the initial loading state of web pages, providing a faster and more efficient user experience. So here for example we can see some numbers we had we made in our book. For the home page we had a two second white screen and now with the static site generation that we added on, like where we modified our home page to use this type of rendering, we have an instant display on the web app. For the data visualization page we added server-side rendering and before with a single page application we had a five second loading state where we had seen the page but it was loading the data. Now since we are doing all the implementation and fetching the data on the server side, in less than a second we will display the data. Concerning the creation of a new data page, it's still in progress. We didn't work on it yet but we are going to use the client side rendering for it since there will be a lot of interactions between the users and the web app. In conclusion, with Next.js we can improve the performance of our applications since we have automatic code splitting and different types of rendering that we can put on the different pages. But if we do not use the rendering in the correct way we might decrease the performance of applications. So we need to think more of how to do the renderings.

That's it, thank you!

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

A Guide to React Rendering Behavior
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
Speeding Up Your React App With Less JavaScript
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Top Content
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.
Routing in React 18 and Beyond
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
React Concurrency, Explained
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
Top Content
React 18! Concurrent features! You might’ve already tried the new APIs like useTransition, or you might’ve just heard of them. But do you know how React 18 achieves the performance wins it brings with itself? In this talk, let’s peek under the hood of React 18’s performance features: - How React 18 lowers the time your page stays frozen (aka TBT) - What exactly happens in the main thread when you run useTransition() - What’s the catch with the improvements (there’s no free cake!), and why Vue.js and Preact straight refused to ship anything similar
The Future of Performance Tooling
JSNation 2022JSNation 2022
21 min
The Future of Performance Tooling
Top Content
Our understanding of performance & user-experience has heavily evolved over the years. Web Developer Tooling needs to similarly evolve to make sure it is user-centric, actionable and contextual where modern experiences are concerned. In this talk, Addy will walk you through Chrome and others have been thinking about this problem and what updates they've been making to performance tools to lower the friction for building great experiences on the web.
Optimizing HTML5 Games: 10 Years of Learnings
JS GameDev Summit 2022JS GameDev Summit 2022
33 min
Optimizing HTML5 Games: 10 Years of Learnings
Top Content
The open source PlayCanvas game engine is built specifically for the browser, incorporating 10 years of learnings about optimization. In this talk, you will discover the secret sauce that enables PlayCanvas to generate games with lightning fast load times and rock solid frame rates.

Workshops on related topic

React Performance Debugging Masterclass
React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
Featured WorkshopFree
Ivan Akulov
Ivan Akulov
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 🤐)
Building WebApps That Light Up the Internet with QwikCity
JSNation 2023JSNation 2023
170 min
Building WebApps That Light Up the Internet with QwikCity
Featured WorkshopFree
Miško Hevery
Miško Hevery
Building instant-on web applications at scale have been elusive. Real-world sites need tracking, analytics, and complex user interfaces and interactions. We always start with the best intentions but end up with a less-than-ideal site.
QwikCity is a new meta-framework that allows you to build large-scale applications with constant startup-up performance. We will look at how to build a QwikCity application and what makes it unique. The workshop will show you how to set up a QwikCitp project. How routing works with layout. The demo application will fetch data and present it to the user in an editable form. And finally, how one can use authentication. All of the basic parts for any large-scale applications.
Along the way, we will also look at what makes Qwik unique, and how resumability enables constant startup performance no matter the application complexity.
Build a Headless WordPress App with Next.js and WPGraphQL
React Summit 2022React Summit 2022
173 min
Build a Headless WordPress App with Next.js and WPGraphQL
Top Content
WorkshopFree
Kellen Mace
Kellen Mace
In this workshop, you’ll learn how to build a Next.js app that uses Apollo Client to fetch data from a headless WordPress backend and use it to render the pages of your app. You’ll learn when you should consider a headless WordPress architecture, how to turn a WordPress backend into a GraphQL server, how to compose queries using the GraphiQL IDE, how to colocate GraphQL fragments with your components, and more.
Next.js 13: Data Fetching Strategies
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
Alice De Mauro
Alice De Mauro
- 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
Create a Visually Editable Next.js Website Using React Bricks, With Blog and E-commerce
React Summit 2023React Summit 2023
139 min
Create a Visually Editable Next.js Website Using React Bricks, With Blog and E-commerce
WorkshopFree
Matteo Frana
Matteo Frana
- React Bricks: why we built it, what it is and how it works- Create a free account- Create a new project with Next.js and Tailwind- Explore the directory structure- Anatomy of a Brick- Create a new Brick (Text-Image)- Add a title and description with RichText visual editing- Add an Image with visual editing- Add Sidebar controls to edit props (padding and image side)- Nesting Bricks using the Repeater component- Create an Image gallery brick- Publish on Netlify or Vercel- Page Types and Custom fields- Access Page meta values- Internationalization- How to reuse content across pages: Stories and Embeds- How to create an E-commerce with Products’ data from an external database and landing pages created visually in React Bricks- Advanced enterprise features: flexible permissions, locked structure, custom visual components
React Performance Debugging
React Advanced Conference 2023React Advanced Conference 2023
148 min
React Performance Debugging
Workshop
Ivan Akulov
Ivan Akulov
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 🤐)