Next.js is a compelling framework that makes many tasks effortless by providing many out-of-the-box solutions. But as soon as our app needs to scale, it is essential to maintain high performance without compromising maintenance and server costs. In this workshop, we will see how to analyze Next.js performances, resources usage, how to scale it, and how to make the right decisions while writing the application architecture.
High-performance Next.js
AI Generated Video Summary
Welcome to High Performance Next.js. Next.js solves the problem of slow loading times and bad SEO performance. Client-side rendering allows for lazy loading, positive UIs, and smooth user experiences. Server-side rendering provides a cheaper option with better SEO and initial page load time. Server-side rendering has benefits such as improved SEO and the ability to create dynamic experiences. Caching is the secret to making Next.js fast, and it can be achieved through static site generation or using a CDN.
QnA
Introduction to High Performance Next.js
Welcome to High Performance Next.js. I'm Michele, a senior architect at Neoform, a Google developer expert, and a Microsoft MVP. Find me on Twitter for staying in touch. Q&A session at the end.
Okay, so, welcome, everyone, to High Performance Next.js. Before we start, let me introduce myself very, very briefly. My name is Michele. I am from Milan in Italy. I work as a senior architect at Neoform. I'm a Google developer expert and a Microsoft MVP. And you can find me on Twitter. This is where I live most. If you're interested in staying in touch with me, this is where you can find me basically every hour of the day. I'm also the author of Real World Next.js, which is a book that, as you might guess, talks about Next.js. If you're interested in talking about Next.js, we will have also a Q&A session at the end of this workshop. So, before the end of the call, we will have the possibility to share our thoughts. I can answer to any of your questions, hopefully.
Introduction to Next.js and Client-Side Rendering
Let's start by asking ourselves, what is Next.js? It's a server side rendering framework, basically for React.js. Next.js solves the problem of slow loading times and bad SEO performance that can occur with client-side rendering. Client-side rendering can result in long loading times, which can lead to users abandoning a website. Additionally, search engines like Google may not be able to index content built with client-side rendering, impacting SEO. Client-side rendering has its advantages, such as making your app feel like a native app with quick transitions.
So, another very quick poll. How many of you have participated to React Summit as an attendee or speaker? Okay. A couple. Oh, wow. A lot of people. Okay, great. So, how many of you have seen my talk about Next.js? Okay. Great. So, I will test if you were paying attention. Because part of this workshop is based on that talk. And I will give you whatever you need to be able to write the Next.js app. I didn't want to repeat myself. But that happens. Sorry, I see one hand up. Sorry. What's your name? Draziner. Do you want to say something? Okay. No worries. Never be worried about interrupting. Oh, thank you. It was amazing. Thank you. Never be worried about interrupting. At any time, please, write me in the chat or raise your hand. I will give you all the time you need for asking questions. Don't worry about that.
So, I know at this point, many of you have followed the talk, so that might be a bit repetitive, but I need to repeat a couple of concepts about Next.js taken from my talk so that we are all on the same page before proceeding any further. So, let's start by asking ourselves, what is Next.js? So, Next.js, as we all know, it's a server side rendering framework, basically for React.js. And it basically wants to solve a problem that React has as an intrinsic problem of the nature of React itself.
So, basically, when we build a single page application or an entire application with React, this is what we get when we first load the page, right? We see a spinner and we have to wait for the whole to get transmitted from the server to the client. Then the client has to render the JSX. And eventually, after some time, we end up having our website. And we can start browsing the website after the hydration process. So, as you may guess, it depends on the kind of website that we have. The performances can really vary. So, if you are good developers and we defer a lot of loading, we lazy load stuff, we might be in that scenario for a very tiny period of time. But if we have a very large application, that can take up to several seconds, which is very, very bad. We all know that given the Google researches, people tend to abandon a website if there's no content after four seconds. So, we really care about time to first byte, first content full paint, and all the metrics that we need to determine if our website is performant enough or not. So, this is the problem with client-side rendering mainly. So, better performances on first load and also bad performances on the SEO, so Search Engine Optimization level. Nowadays, Google is capable, specifically Google, it's capable of indexing content built in the virtual DOM by react, angular, view, etc. But we also have to think of other kind of search engines. So, for example, if we care about the Asian market where Google is not the number one search engine, we have Yandex, for example, which is not capable as for today as far as I know through index content created by react or virtual DOM content. So if you let's say you build an online e-commerce that targets specifically the Asian market, then you might be in trouble because Google is not the number one search engine there. So we can't guarantee a good SEO result for our web application. And again, please let me know if you have any questions. This is the right time to to ask for them because I can explain more in detail if there's something that I'm missing or you need more information about.
So okay, basically client-side rendering so we will call this CSR from now on has pros and cons, right? So it makes your app feel like a native app. So when you're browsing your single-page application, it feels like you're on a smartphone, right? Because you have super quick transitions.
Benefits of Client-Side Rendering
Client-side rendering allows for lazy loading, positive UIs, and smooth user experiences. Positive UIs presume that everything will go right at first, displaying content and allowing actions even when offline. The concept is easy to implement with client-side rendering applications, as everything is already in the JavaScript bundle. This approach eliminates the need for continuous communication with the server and page refreshes. It also makes page transitions easy and reduces server-side workload. Static assets can be deployed on a CDN without the need for a server, making infrastructure cheaper to maintain.
Everything is already loaded into the browser and we just have to render it. So there's no page refresh and continual communication through the server and waiting for the response to refresh the page. We can make everything extremely lazy and by lazy I mean that for example, we might not have the content for let's say we have a single page application that it's a blog right. We might not have all the pages for the blog. Of course we will need to ask the server for the data to be inserted in every single page but we do that lazily.
Every single time we want to access a page and we can make like positive UIs. Do you know the concept of positive UIs? Thumbs up if you do. Otherwise I can explain. I can try to explain. Okay great. I will explain. So for example, how many of you are on Instagram? No one? Okay. Now it makes sense. So basically Instagram is a perfect example of what a positive UI is, right? It means that, for example, you're offline, you have in cache a list of posts, you can double tap on a post to give a like, right? But if you're offline, there's no way that you can communicate with the server because you're offline, right? But it will say, okay, you gave a like. And as soon as I go online, I will send these communication to the server so that the like can be propagated to the user receiving the like, for example. So this is an example of positive UI. We presume that everything will go right at first time. And if anything fails, we will just give a warning. So that's the case for client side rendering, for example. We can deeply exploit this kind of psychological user interface and user experience where we say, OK, you're asking for that page, I will preload the page with a skeleton loading, et cetera, and I will assume that the server will send me the data to be rendered on the on the on the page. And if the data is not available in the in the database, for example, I will just give you an error. No problem. Otherwise, you have a very smooth user experience. And this is really, really important when you're writing web applications. Please let me know if that makes no sense. Let me see in the chat.
Okay, Dimitri is asking, is the positive UI a kind of progressive web app progress, oh sorry, yeah, PWA? So, yes, let's say I wouldn't merge the concept of positive UI with the progressive web apps. And that's because the positive UI, it's a way of designing and thinking about your application. And it's really easy to implement it with clients and rendering applications, for example, or native applications. Because you already have everything inside of your JavaScript bundle. So you don't have to continue communicating with the server and refreshing pages every single time. You just assume that everything will go all right. You want to leave a comment, it doesn't matter if you are not able to reach the server at this time. You can show the comment right now on your blog post and retry several times until you can reach connection or just give an error after a fixed amount of time. So this is a very good advantage I see in exploiting client side rendering capabilities. And I really wanted to go deeper into that concept, which is something I couldn't explore during my talk because of time limitations. But, again, now it's the correct time to expand on certain concepts. And so, yeah, we cover why it makes you feel your app feel like a native app. Why page transitions are so easy, because you basically don't have to refresh the page, right? So you just make a transition from one page to another. Lazy loading and performances, we already covered that. And less server-side workload. So basically, how many of you have ever tried create react app? Okay, okay, several people. That's super cool. So you perfectly know that, for example, when you have a create react app application, you only need basically one HTML file, CSS, and JavaScript, which are all static assets. Once you have static assets, you take those assets, you deploy them on a CDN, on AWS S3, and you don't need a server at all. You just take this aws-s3, and you don't need a server at all, you just take these files and throw them on something that will serve them for you. You don't need a server at all. You might need an API server, but that's something else. We will discuss this later. You only need to serve static assets, which makes, first of all, your infrastructure way cheaper because you don't have to maintain a server, which means you have less...
Benefits of Server-Side Rendering
Server-side rendering provides a cheaper option with better SEO and initial page load time. Next.js and other frameworks like Razzle and Angular Universal offer server-side rendering, where the server pre-renders the page and then hydrates it with JavaScript. This approach enhances security by hiding critical calls and protecting against man-in-the-middle attacks. It also allows access to HTTP only cookies and improves compatibility with older browsers. Additionally, server-side rendering improves search engine optimization.
It's a cheaper option. You don't have to maintain. So you don't have to pay a person for maintaining a server, security releases, and I don't know, a runtime upgrades, whatever. So that's super, super cool. And we already see the costs of client-side rendering. So bad for SEO and bad for initial page load time. So we know something about that already.
But the problem is that these cons are really bad for modern web development, right? So this is where Next.js alongside other frameworks such as Razzle or I don't know, Angular Universal, Nukes, and so on. They provide a new way for rendering React, which is server-side rendering. Okay, so while with client-side rendering we see a loader, spinner or whatever when we first access the page, this is not the case for server-side rendering, where as soon as we make a request, the server will pre-render the page, of course, on the server and will transmit the final page to the client. We already know that. So eventually we will have the pre-rendered page on the client itself. After that there will be a process called React Hydration which will basically make our application interactive, so we can start if we have, like, a used state, if we have a used context, if we have any hook running or any JavaScript script running on the client, this is where Hydration will run and will make JavaScript interactive on the page.
Pros and cons again, web applications might be a bit more secure and that's for a very simple reason. So, imagine you have a client side rendered application and you have, like, what's the name, an account page where you can update your password, for example, okay? What happens at this point? You want to update your password, you have to communicate with the server and you have to send a new password to the server. How many of you are familiar with the concept of man-in-the-middle? Okay. Okay. Cool. A lot of people. Let me okay. Let me give you a short example for the people that is not really familiar with that. So man-in-the-middle is a kind of attack which is a big security concern that basically let's say you are in a public hotspot and you're connected to a free Wi-Fi source. Well, you don't know who is basically running this Wi-Fi. So whoever it is, they can have access to the data you're transmitting from the client to the server. So if you are sending a password and it's not well encrypted or end-to-end encrypted, this person could potentially see your password and use it. And I'm 100% sure that the vast majority of us, it's using the same password for bank accounts, Facebook, Instagram, Twitter and whatever. I'm not blaming anyone, I'm one of those, I know, but that's what happened and that's why we really care about this. If we have a server, that means that certain critical calls can be run server to server. So the traffic is hidden for malicious users. That also means that we have access to HTTP only cookies, which also means that browser extensions or third-party scripts cannot have access to the cookies on the client side. So this is a big game changer when it comes to security. And that's because there is no... Basically we can hide traffic from the users of our website. Let me see in the chat. I got my password hacked before. It was a real pain. I recommend using something like LastPass. Yes, absolutely. If you are an Apple user, just use the built-in tools in Apple. I use 1Password and it's working very, very well. Absolutely. This is a very good suggestion. Thank you. So we can basically... We were saying we can basically hide our traffic rate. Another pro is that we have more compatible websites. So given that we render everything on the server side, it means we are sending an HTML5 directly to the client and the browser. If JavaScript is not enabled, for example, on the browser you can still navigate the website in some ways, and that's because you can fall back to links instead of state route push, etc. It depends on how you manage your website, but technically speaking you might have a more compatible website even on older browsers. Enhanced search engine optimization, of course we have that.
Server-Side Rendering and Static Side Generation
Server-side rendering has benefits such as improved SEO and the ability to create dynamic experiences for different users. However, it also has drawbacks, including the need for a server and high maintenance costs. On the other hand, static side generation is a rendering strategy that builds pages at build time, resulting in static pages that are easy to scale and have optimal performance. It eliminates the need for a server and provides secure requests. However, it may not be suitable for handling private information and is not susceptible to distributed denial of service attacks.
And that's because, again, we have already rendered all the HTML, so the search engines will be able to index the content way easily. They don't have to wait for the virtual DOM to load and then to wait for the content to show up. And also highly dynamic content, which means that we can create new pages depending on who is browsing the website. So a very quick example. Let's say I am one of the users and I see first on my screen Logan. So I will take you as an example. Let's say I am logged in as Michele. Logan is logged in as Logan. We could have two very different experiences directly from the server side because of our users. So we are different users. We might have access to two different experiences, right? Okay. So this is not nice to have.
There are also some cons. First of all, a server is required. So there's no way we can run server side rendering without a server. Those days we have many different alternatives for server side rendering. We have, for example, serverless environments. So we can deploy our application to AWS or Google Cloud or Azure functions. We don't need a server in a strict term. We can use serverless environment or we can use Google Cloud run or EC2 and AWS. We can use whatever we want. But we need to maintain something. Or we need to pay someone that maintains that for us. So if you follow my talk, you know what I'm talking about. I mean, the costs are really, really high. So higher server workload means that as soon as the server gets a certain number of requests, so we have more requests coming, there will be more workload. We will need to scale or in the case of a serverless environment, we will need to pay a lot for running for making our application scalable. That also leads to a higher maintenance cost. So let's say you are running a Kubernetes cluster with a number of pods and a load balancer balancing the traffic amongst all the pods. This is something we have to maintain. This is not something easy. And let's say there is a very high security fix on nodejs 16 and we want to upgrade it, we have to upgrade the image of our containers on several different pods. And then we want to upgrade to node 18, so we have to run another maintenance operation, you know. So while server side rendering, it's giving us many ways for keeping stuff easy, make it compatible, make it secure. It also has some very heavy drawbacks. So that's something we want to keep in consideration.
Last, but not least, one of my favorite rendering strategies. So static side generation. So it's quite similar to server side rendering, except we build the pages at build time. That means that it's super easy to scale, because we end up having only static pages, right? So we don't need the server. We don't need a server on the backend, because we already have built everything at the build time. Performances are the best performances possible, and that's because we already rendered everything. There's no server workload at all. We only take a file from a CDN and serve it, or take a file from a server and serve it again. Requests are typically secure for another reason. It's a different way of thinking of security in that sense. We don't have a server, which on one side can allow us to deal with the security with private information, but not having a server also means that that might not be subject to, for example, distributed denial of DDoS. Sorry, it's really difficult for a non-native English speaker to talk about that.
Serverless Architecture and Caching in Next.js
Not having a server can provide security benefits, but it also means vulnerability to DDoS attacks. Next.js offers security features and the ability to adopt different rendering strategies for each page. Caching is the secret to making Next.js fast, and it can be achieved through static site generation or using a CDN. Caching not only improves performance but also reduces costs. It's recommended to use static site generation in most cases, although there are exceptions. Next.js can be gradually migrated from a React application, and an API gateway can be used for routing traffic to Next.js.
We don't have a server, which on one side can allow us to deal with the security with private information, but not having a server also means that that might not be subject to, for example, distributed denial of DDoS. Sorry, it's really difficult for a non-native English speaker to talk about that. Sorry. So, we might not be subject to DDoS, for example, attacks, because typically if we deploy our website, for example, on CloudFlare pages, CloudFlare is built to resist this kind of attacks, right? It's built to resist slow lowers attacks, for example. So, we have another kind of security in that sense. And depending on the content of our website, depending on the purpose for our website, this is something we want to keep in consideration.
It also has some cons. We already know that. So, no dynamic content on the server side. So, again, if I log in and another person logs in with a different user, we would have the same experience, basically, unless we render stuff on the client side. And in fact, it has to rely on client-side rendering for dynamic content. And the worst part is, if we have a very large website with like, I don't know, 1 billion pages, and we made a typo on one of those, we have to rebuild the entire website to fix that type, right? And thankfully, Next.js fixed that with incremental static regeneration. So, we will see that in a second.
One nice thing about Next.js, we already know that, it's hybrid rendering, means that for every single page, every single page in our website can adopt a different rendering strategy. That's really important to know. Then, I see, sorry, I'm going through the chat. Okay, I see, Logan saying, personally, I have found SSR to be not to be much better load time than CSR, SSG seems better in almost every case. 100% agree on that. You're anticipating something I wanted to say later on, which is very good. If you want the secret of making Next.js fast, the secret is, we can say that in like one second. This is a three hours workshop. I didn't want to say that at the beginning, but we are already there, so let me say it. When you need high performance in computer science, you typically do two things, caching and queues. In that case, we have caching. So you can either use static site generation, which is basically an incremental static regeneration. So that you build the page, you pre-build the page at build time, or if you are in the situation like Logan where you say, SSR, it's not much better than CSR. And I totally agree with you, in that case, you want to use a CDN in front of your website so that you can cache the response and serve the response without hitting the server every single time. This is the real secret of making every web application fast. And Next.js, it's not an exception. One nice thing that you notice when you start writing Next.js applications is how Versailles specifically, so the team behind Next.js is good at dealing with the cache. If you look at the caching headers, caching mechanisms, they do an awesome job for all of us. So caching, it's the answer for running a very fast Next.js application. And it's also the answer for making it cheap. Because if you hit the server every single time for server side rendering, I mean, this is costly. You pay every single time, it hits the server. But if you have a CDN, you pay for every billion of requests, every million of requests, which is way cheaper than a server. So yeah, I totally agree with you. And static site generation is in my opinion the way to go for most of the cases. But there are some exceptions, and we'll see them later. Okay. Oh, thank you, Joseph. I'm glad you're here too. And Navid says, can we have Next.js in some part of our current React application that needs SSR or SSG? So if you mean that you already have a React application and you want to transform it into a Next.js application, there is a way to do that. There are ways to do that. I think there is also a code mod on the Next.js repository that helps you transform your current React application into Next.js one. From now on, you can basically just use Next.js and decide to use static site generation, site rendering when you need it, and whatever. Oh, okay. If you mean gradually migrate to Next.js, okay, things are getting more interesting at this point, but we will be going into software architecture. Meaning that you could have, like, an API gateway somewhere saying, okay, all the pages under, let's say, slash blog, now I will route this traffic into a Next.js application. All the other routes create React app.
Server-Side Rendering and TypeScript Performance
Two distinct servers serving different applications can be achieved with a reverse proxy or an API gateway. Sharing components between Next.js and React is easy. The performance of SWC, a good builder, is impressive. The creator of SWC is porting the TypeScript compiler to Golang, promising better performance in Next.js and TypeScript. The project is supported by Versal.
So, two distinct servers serving two different applications. You can do that with a reverse proxy, for example. Like, engine X, caddy, or whatever. Or you can do that with an API gateway. So, you can route the traffic on some routes goes on Next.js, other routes goes on React. One nice thing is that you can share components. So, it should be quite easy to do it.
Okay. Logan says just the difference in build time over React app is worth it. Yeah. And Felix is also right. SWC is such a good builder and the performance is insane. Yes. I totally agree with that. And I don't know how many of you are aware of that. But let me ask a question. How many of you are writing TypeScript? Oh, I'm super happy to see people writing TypeScript. You've got to know that. Awesome. Okay. So, the creator of SWC, it's now writing a porting of the TypeScript compiler in Golang. So, hopefully, we will also have awesome performances during type checking in Next.js and in TypeScript in general. How cool is that? And this project is also supported by Versal, so I'm a huge Versal fan, is my guess.
Accessing User Cookies in SSR and SSG
Accessing user cookies in SSR and SSG can be challenging. With SSG, server-side cookies are not accessible, which can be a security concern. Cookies can be a potential source of hacks for web applications.
Okay. Ibrahim, how much easy is it to access user cookies in SSR and SSG in case of session-based auth? This is a good question, actually. So basically, the biggest problem I see with cookies, as we were saying before, you don't have access to server-side cookies with SSG. So basically, it means that if you have HTTP-only cookies, you really need server-side rendering to get these cookies. Why do you want server-side-only cookies? For security concerns so that if you incorporate third-party script, browser extensions, they won't have access to the cookies. So this is why I find cookies to be a bit dangerous and a source of big hacks for any web application, not just JavaScript based.
StaticSite Generation and Authentication
StaticSite Generation is not made with user information in mind. You would have to go with SSR. However, you can use authentication and user sessions with client-side rendering. If you're interested, my book has a chapter on building authentication from scratch and using Auth0.
Sorry, I see Savinda raising their hand. I don't know if you have something to ask. Oh, no, I guess not. Okay. Felix says, as far as I know, StaticSite Generation is not made with user information in mind. You would have to go with SSR. This is correct, but I would also like to point you to, for example, Auth0, right? So if you are using Auth0 or AWS Cognito or any identity provider, they have SDKs for client-side only applications. Maybe you don't have to use cookies. So that's my point. You can still use authentication. You can still use user sessions with client-side rendering. So also, StaticSite Generation. It's just a different way of dealing with it. And in my opinion, it's a bit more insecure if you're not aware of all the risks that comes with that. So if you use the official SDK for Auth0, I'm super happy with that. If you have to implement your own authentication, okay, then things become to get more interesting, you know. Is there anyone... Okay. This is a strange question. I'm sorry. Is there anyone who wrote my book yet? Didn't want to promote. Just asking. Okay. In my book, there is an entire chapter describing how to build authentication from scratch, so how authentication works, and why you should use Auth0, for example. So if you're interested, I'm sorry. I didn't want to promote my book so bad, but there is an entire chapter talking about that and how to deal with authentication. Okay. Okay. Thank you for buying it. So let me go with a couple of more explanations, then we can start dividing in teams and work all together.
Rendering and Incremental Static Regeneration
Rendering involves making a request to the server and receiving a blank page with the JavaScript bundle. The page is built piece by piece, resulting in a complete page after several seconds. Server-side rendering eliminates the need for this process. Static side generation allows the server to send back the complete page without rendering. Incremental static regeneration enables rebuilding of specific pages after a set time. Changes made to a page are reflected for users after the specified time period.
So let me explain rendering for those who are not very familiar with the naming. So basically, you make a request to the server. As soon as you make a request, the server sends you a white page, a blank page with the JavaScript bundle. As soon as the bundle gets, what's the term, gets interpreted by the JavaScript engine on the browser, it starts to build the whole page. Okay? So as you can see, as time passes by, we compose the page one piece at a time. So we might need several seconds, again, to have our page complete. This is not the case for server side rendering.
So you make a request, you wait several seconds at this point, if the page is really heavy, of course, on the server, you wait for it, and you get back the complete page after several seconds. With static side generation, you ask for the page, the server already has it, it doesn't have to render anything, and it will send back the page and you're done, so that's all you need.
And okay, sorry, I see a couple of questions. Oh, thank you for sharing the book. You can also buy on Amazon, if you prefer. Okay, so as we were saying, this is super cool, right? Static side generation is super cool, but still, you need incremental static regeneration that basically allows you to allow you to rebuild a particular page after some, let's say, after x seconds have elapsed. So for example, let's say you have a typo. No, no, let me explain with this example. Let's say we have this web page, okay? We say that every five minutes, we have to check if there's a change in that page, and if there's a change, we have to rebuild the page, and remember, this is a statically generated page. So after one minute of the publication, one user comes, they will see that page, right? After three minutes, another user comes and see that page again. After five minutes, because that's a lazy operation, another user comes and sees the exact same page as for the other users. So five minutes has passed. The next user will trigger a new build for the page. So the next user, after five minutes, will see the page, the new page, which in that case shows an Irish setter instead of an English one, dark background, et cetera. So after four minutes, another user comes and we'll see the same. And after five minutes, another user will see the same page again. And now there is an error. You see, this is an Irish setter, not an English one. So if we want to publish a change, because there's a typo, after five minutes, we will have a whole new page for the next users. So-
Sorry to interrupt, but why does the whole content change? I don't get that.
Oh, okay. No, no problem. So let me go here. Let's say we want to change that page. Okay. The page content. We don't want to rebuild the entire website, right? Because maybe the- let's say this is a very big website. So we don't want to rebuild it. Because maybe it takes like let's say- I've been working in a company where the whole build process took like three hours. So it means that if we have a problem on a content coming from an API and we have to change, for example, the background color from light to dark, we have to wait three hours. And that's just an API call telling you the color for the background, right? So with incremental static regeneration, we basically statically generate this page and we say, okay, Next.js, every five minutes when a user comes, look in the database or look at the APIs, look at the data inside, get static props, re-execute, get static props, and re-render the page every five minutes if there's any change. If there's no change, we will keep it as is. If there's a change, for example, let's change the dog image and the background color, then apply the change. In five minutes if there's no change, we will keep it as is. I hope it's a bit more clear now.
Yeah, thank you.
Okay.
Okay, no problem. It's good that you ask. Please everyone ask questions as much as you can. So why this is something that it's a bit confusing, because I say that this page is statically generated. Well actually it's not. Beware of that.
Incremental Static Regeneration and AutoCannon
Incremental static regeneration means setting HTTP caching headers and running the page under server-side rendering again. You still need a server. Install AutoCannon, a powerful tool for stress testing and benchmarking your applications. Remember to use it only on your local machine and not against live servers. AutoCannon provides latency, request per second, and benchmark percentage data. It's a perfect tool for measuring performance.
Incremental static regeneration means that we set some HTTP caching headers. So the page is run under server side rendering again, but we have some caching headers. So it's not a static page. You still need a server. Okay. I want this to be very clear.
Okay. So I've prepared a very, very simple Next.js application. You can find it here. Please clone this repository and thumbs up when you cloned it. One requirement for this workshop was to have Node.js installed on your machines. So I hope everyone of you has Node.js installed.
Okay. Cool. So this is what we'll do. You will need to install AutoCannon. How many of you are familiar with AutoCannon? Okay. You will like this. Sorry. I have this very big zoom window, and I can't see anything on my computer. Oh, my God. This is so bad. I can move it. Okay. So let me show you. AutoCannon, it's a super powerful tool for stress testing your applications, which is also giving you some benchmarks about how it performed. So never try this against a live server. Only do that on your local machine. It is not legal to run DDoS attacks against any server, which is not yours. Please remember that. But this is super useful for us. And I will show you how.
So you basically have to install it. So npm install auto cannon. Let me share with you the command again in chat. Just install it. And there are a number of options. I would like you to experiment with those options. And it will give you the following output. So it will tell you the latency. Let's say by default, it runs on 10 different connections. It runs, in that case, 250,000 requests in 10 seconds. And it will show the latency after 50% of the benchmark, 97% of the benchmark, etc. And request per seconds as the benchmark goes on. So if we talk about performance, we need some numbers, right? This is a perfect tool for measuring performances. So show me your thumbs. How many of you have installed AutoCanon right now? Awesome. Awesome. Good. So this is the first task.
Building and Profiling Next.js Apps
You have 15 minutes to build the Next.js application, run AutoCanon against it, and compare the results. Then, try Node Clinic, a profiler for Node.js applications that supports Next.js. Install Clinic and run the provided script to identify potential performance issues. Node Clinic offers various features like Node Clinic Doctor, BubbleProf, Flame, and the heap profiler. These tools are essential for enhancing the performance of your applications.
You have 15 minutes. You have to build the Next.js application, run AutoCanon against it. So please read the documentation. I wanted to collaborate. Then, inside the application, you will see the Next.js app. If you go on there is only the index page because that's what we care about now. If you're looking at my screen, you will see GetServerSideProps. And you will also see that I have commented GetStaticProps. So you will need to change GetServerSideProps, comment this, uncomment this, and run Autocannon again. Then you have to compare the results. Then we will go back to the main room, so the one where we are now, the main room, and we will comment the results together. Okay? So you will see, if you go on API for products, that I created a random latency function, which means that it will give you up to five seconds latency for every API call, for composing the homepage. So don't worry if it's slow. This is on purpose. Okay? And my suggestion for running this task, would be choose one person which will share the screen, and then you can start coordinating the efforts. Okay. So let's move on.
Okay. So task number two, I would like you to try Node Clinic. How many of you are familiar with Node Clinic? Okay. Let me do the other way around. How many of you are not familiar with Node Clinic? So Node Clinic, it's another tool built in NearForm, the company I work for. AutoCanon was one of those, Node Clinic is another one of those. And basically, Node Clinic is a profiler for your Node.js applications. And now it also supports Next.js. So there are many things we can do. For example, Node Clinic Doctor. So, basically, you can run Node Clinic behind AutoCanon and it will profile and find potential issues in CPU usage, memory usage, etc. BubbleProf, which is a bit more trickier. You can see which function has basically a dependency on another function, or is triggering another function again, etc. There is Flame, which is awesome. It gives you a flame graph of the V8 and GNOME Node.js, of your dependencies, of WebAssembly, whatever you need. And the heap profiler, of course, which provides the heap for the Node.js runtime. So, when we talk about performances, also in Next.js, of course, we will need these tools. So, AutoCanon and Node Clinic are two of the tools you want to have in your toolset. For, you know, helping you understand how to enhance the performances of your applications. So, the next task would be install Clinic. Sorry. Let me take the… Should be just Clinic on npm. Yes. So, just install it. Let me share with you… Okay. The command. Install it. And another 15 minutes, you have to build your Next.js app and run the below script. So, let me copy and paste the script. I do expect to see a problem. So, it… I mean, I made some tests and it showed some problems. I want to see if you had the same… Okay, sorry. Stop the sharing.
Finding Application Errors with NodeClinic
I want you to find an error that is slowing down everything in your applications using NodeClinic.
I want to see if you find the same problems. Run it with SSR or SSG. In that case, I would say try with both. But in that case, with a doctor, I would expect the very similar results. So, it's not about performances in that case. Why not both.jpg? Yeah. It's not about the performances, but about the way you can look up for errors in your applications. And there is one. And I want you to find that error. It's not a bug, but it's something that is slowing down everything. So, I want you to find this using NodeClinic.
Creating Pages and Justifying Rendering Methods
In this task, you will create a page for each product and justify the rendering method for each one. ADRs, or Architecture Decision Records, are a valuable tool for determining infrastructure and discussing with colleagues and managers. ADRs help address issues and propose new solutions. For example, if you're building a social network web app with a common homepage that shows user-specific content, ADRs can guide your decision-making process. Consider options like static site generation or server-side rendering for the page.
Okay, so I had a question from Joseph. I will be going over the use cases all for using either SSG, SSR, or it's as IR. By chance. Yes, absolutely. And actually, I'd like you to be thinking about that. And I will be reviewing your ideas.
So, let me share my screen again. Okay, sorry, I was on GitHub. Okay. So, this is task number three. And this is where I want you to really think about what's the best solution. I will divide you again in the breakout rooms. And you already have the products. I want to create a page for every single product. And I wanted to justify which rendering method will you use for every single product. How does it sound? Any question? The idea would be to have one person sharing the screen and writing code. And the other people helping this person. Okay. Every time you have a problem, please write me in the chat here in Zoom. I will be there for helping you. And I'd love to hear some discussion in the team to determine which is the best solution. And how would you approach that as it was a production solution.
I will share with you the slides so you can continue the workshop on your own. But we don't have time to go through the next slides. But I want to talk to you about ADRs. How many of you are familiar with the concept of ADRs? Okay. So ADR is short for Architecture Decision Record. And that's because, as we were saying at the beginning, thinking about Next.js, it's also a work for a software architect. Because this is not only engineering. You have to see your whole infrastructure to determine how to support high loads. So ADRs are an amazing way for determining how to create our, let's say, our infrastructure or our web server or whatever. And it's also a good way to discuss this with your colleagues and also with your manager.
So let's say you have to write a social network web app just like Instagram, like in my talk. You told me many of you watched my talk so you already know where I'm going. And let's say the homepage is common for every single user. The content changes depending on the user logged in. So we don't have 20 minutes right now. But I will leave you this. Let me take this link. I will share in the chat. I would like you all to get known to the ADR. So if you have a doubt, if you don't agree with your manager and you want to be efficient in telling what's wrong about the current solution or you want to propose something new, well, the ADR is the right way to proceed. So, you basically have a title for your ADR. For example, social network homepage, okay? Context and problem statement. It might be like I have to build a social network. I have a homepage. The homepage shows content depending on the current logged in user. And we have a lot of traffic, a lot of static assets. So, this is the kind of problems you need to deal with, right? Consider options. So, we could go with static site generation for the page or server-side rendering for the page.
Choosing Static Site Generation
We could use incremental static regeneration. The best option, in my opinion, is static site generation. It allows for highly dynamic content and doesn't require Google to index the homepage. However, changing the logo may require relying on incremental static regeneration or rebuilding the entire website. It's a comprehensive way of making architectural decisions and documenting them. ADR templates can be found on Google. Follow me on Twitter, LinkedIn, and GitHub for more information.
We could use incremental static regeneration. So, these are the options we are considering.
Decision outcome. We decided as a team or I decided as an individual. By comparing my option with my manager's options. That, for me, the best option is, and I'm giving you mine, static site generation.
Why is that? So, positive consequences of static site generation, in my opinion, is that the content is highly dynamic and depends on the user that it's logged in, right? So, it means that if I log in and another user logs in, we will see different feeds, for example, on Instagram, depending on the people we follow. So, it's not really important for Google to index the homepage. Google only wants to index, you know, the header, the titles of the social network, et cetera. Doesn't want to index the content of the homepage. So, we can just statically generate it and serve it through a CDN, which is faster, which is more reliable.
What is the negative consequence of that? So, we go down. Negative consequence. Negative consequences are, if we have to change the logo, we have to rely on incremental static regeneration or rebuild the whole website. We know that.
Pros and cons of the options. So, for static site generations, we have pros and cons. For incremental static, sorry, for server-side renderings, we have these pros and cons. And for incremental static regenerations, we have other pros and cons and we put everything there.
More information if I want to give more information to my team, my manager and whatever. So, it's my opinion, and that's a very personal opinion, that this is the best way you can propose something to a team, to your manager, to your colleagues, because there is a formal way for communicating and it's a complete way of determining how you made your choice.
So, given that, as we saw in this workshop, it's more about architecture than engineering at this point, this is the way you deal with software architecture in a very effective way.
Yeah, absolutely. There are many different templates. This is my favorite one. You can look for ADR on Google and see the template you prefer, but the concept is always the same. You give many options, you document your options, and you give your suggestion, and then you discuss.
So, that's also a way for keeping documentation about the decisions you make on an architectural level.
And by doing that, I'd like to share my contacts. So, in the meanwhile, if you want to take my contacts, follow me on Twitter, LinkedIn, and GitHub.
Comments