Advanced Rendering Patterns: Lydia Hallie

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
foreign [Music] [Music] hello everyone good evening my name is lydia helly i'm a staff developer advocate adversel and i'm here today to talk about rendering patterns building on the web has never been more powerful than it is in 2022 but it can feel pretty overwhelming as developers to know which rendering pattern really makes the most sense for my application in most cases we just want to develop preview shift have a great idea share it with the world but in most cases it doesn't quite end up that way quick question i don't have my notes here doesn't matter it doesn't matter but unfortunately in most cases we end up with really long build times and it frustrated users because our website loads data really slow um and we might even end up with really high server costs because or for a website that most people didn't even know existed because the performance was so bad the seo was so bad so people didn't ever discover it so although our idea might have changed the world is the way that we architected our website prevented this from ever happening so what can we do about this we have to start implementing the right rendering patterns knowing how to apply these techniques can massively improve your app's performance giving you a great product to share with the world now usually when we talk about web performance we talk about optimizing for the core web vitals and these are a set of really useful measurements that tell us how well our site performs for example the time to first byte tells us how quickly our server responds with the initial data to make sure that our users don't stare at like a blank screen for too long and the first contentful paint tells us how quickly our users are able to see the first contentful comm our content now i won't go over all of these right now you can probably read it but if we want to have a graph website with a great seo we have to start caring about optimizing for these core web vitals that's not all because we also want to have the best developer experience we want a project with really short build times in order to be able to iterate quickly we want to have low server calls so we don't go bankrupt after a week of just having our project and we want to show dynamic content in a performant way and just generally don't really run into any scalability issues once your website actually goes viral now although this may seem like a lot to keep in mind using the right rendering technique can really help you out there to create a great user and developer experience all right so now that we know why rendering techniques are so important how do you know which one makes the most sense for your website or even if you deploy to your cell you can do this on a per page basis so which one makes the most sense for that page spending one minute on google or on tech twitter can already feel pretty overwhelming with all the terms and abbreviations and latest trendy ways to render data and especially people's opinion on them now all patterns out there have their use cases and there isn't really one pattern that's better than the others they all have their trade-offs so in this talk i'll just walk you through some of the most common ones uh to make it simple i will just show the functionality based on versailles deployment but it applies to everyone all right so first let's talk about a pattern that may seem very basic and straightforward namely static rendering static rendering is a very performant pattern because it comes with so many performance benefits with static rendering the entire html gets generated at build time and these static assets are easily cacheable by a cdn or on for cell by the edge network so this makes it extremely or this makes it possible to get extremely fast responses because we can just return the cache data from the cdn instead of going all the way to the origin server now although it might seem simple there are many variations to static rendering to serve a lot of different use cases and we'll go through all of them so first up is plain static rendering now i'm using plain static rendering just because i didn't really know a better term but we can use plain static rendering for pages that are really not dynamic at all an example is this landing page for this demo real estate website this page is absolutely perfect for steady rendering because it just shows the same data for everyone globally we aren't fetching any data or showing any personalized components so when we deploy this in this case to for cell the html gets generated for all the pages and eventually persisted to static storage now when a user visits the website a request is made to the server which can quickly return the pre-generated html and as it does this the edge location closest to the user actually caches the response now the browser renders the html and optionally requests another javascript bundle in order to actually hydrate these components and hydration is just binding the event handlers to the html in order to make it interactive so from a performance perspective this is a great approach because we can have a really quick time to first byte as the pre or the server already contains the pre-generated html and the browser can quickly render something to the screen resulting in a really fast first contentful page and largest contentful pane and also we don't have to worry about layout shift because the pre-generated html already contains all the components so we aren't like dynamically rendering any components um as users requesting it so play or plane static generation is great for your core vitals but in most cases we probably want to show some dynamic data saying that instead of like just showing the features we actually want to show the recent listings now we could just hard code the data right in the page but in most cases we probably want to use a data provider to fetch the data from one approach we can take here is to use static rendering in general or in combination with client-side fetching and this is usually a great pattern for pages that contain data that should like renew on every request we can simply statically render the website like we did before adventure data with for example using swr on the clients like as soon as the page is loaded and as it's doing that will show a skeleton component or skeleton ui now we do need to create like a custom api route to fetch the data from for example the database or another data provider and call this api route on the client now when a user requests the page the server again returns with the pre-generated html and the user initially sees a skeleton ui since the data hasn't been fetched yet now after parsing and rendering the content the client fetches the data from the api routes after which we can actually see the listings so although static rendering and client-side fetching gives us again a really good time to first bite and first contentful paint the largest contentful paint kind of suffers because we can only show the listings once the api route has actually responded with data after which you can render listings now we may also run into layout shifts and this can happen if either we're lazy and we're not showing a skeleton component at all or the skeleton component doesn't like have the same height and width as the component that eventually gets rendered also since we're calling the api route on every page load we may end up with really high server costs now when you use nextgs you can actually choose between a few more static approaches that really improve the performance of your app when you're using static pages in combination with dynamic or dynamic data one of them is with the get static props method now this method runs server side at build time meaning that we can directly call our data provider within this method this can be like a really good solution if you have dynamic data for pages and the data is already available to you at build time now the get static prompts method run server side so we no longer have to deal with having those custom api routes to fetch the data from and we also no longer have to show that skeleton component because there will never be a loading state because generated html already contains that fetch data now when we build the product the data provider gets called and the return data gets passed to the html so now when we request the page again the server can quickly respond with the pre-generated html it gets cached rendered to the screen and the browser can send a request to optionally hydrate it so from a user perspective it's pretty similar to what we did before with just static rendering without having that dynamic data but from a developer perspective we can quickly run into some issues imagine or pre-building hundreds or thousands of pages using that constitutive prop method which can easily happen if we have an e-commerce website or a blog and if if you want to execute that during your build and it takes maybe half a second to fetch that data you can easily run into really long build times and if you're using an external api that maybe charges for every request you might also end up with really high costs for that third party and another issue is that we're only renewing that data at build time meaning that we have to redeploy the website every time to update the content now luckily we can use incremental static regeneration to solve our build time with the dynamic data issues because with isr we can decide to only pre-render certain pages and render the rest on demand when a user actually requests it now this can result in much shorter build times it also allows us to automatically invalidate the cache and regenerate the page after a certain interval now imagine if we wanted to show individual listings as well and pre-render these pages to get a great performance when a user clicks on the listing using sgs we can have those dynamic paths in combination with the getstaticpaths method to tell next which pages to pre-render and which pages should be generated on demand now in this example we're actually fetching all of the listings so we're actually pre-rendering every single one of them this could easily end up in really long build times instead we can sell next to only pre-render a subset of all the pages and then use or render a fallback while the other list or the other page is generated on demand now the pre-render pages behave the exact same as we saw before but if a user request a page that hasn't been generated yet the generation or the page gets generated on demand but eventually also cached by the edge so this means that only the first user within a certain region might have the worst time to first buy but everyone else just gets the cash response so they get a good time to first bite all right so now our long bill times have been solved but we still don't want to have to redeploy the page every time to renew the data so instead of only renewing the data of build time we can automatically invalidate the cache and regenerate the page in the background on a certain interval and we can do this by adding the revalidate field to the return object by getstatic props so now when a user requests a still page meaning a page that has been cached for longer than this or the number of seconds specified uh they initially will see that still content but in the background we actually pre or trigger a regeneration of that page um so once the page has been regenerated the cache gets or invalidated and updated with that page so now when the user requests it again they will see the updated content so with incremental static generation we can like show dynamic content by automatically revalidating the cat or the page every number of seconds and although this is already a huge improvement to what we saw before we can still run into some issues here because it's likely that our content actually doesn't update every number of seconds which would mean that we're unnecessarily invalidating the page or invalidating the cache and regenerating the page every number of seconds even though the content hasn't actually changed now the best option here is to use on-demand incremental static regeneration so with on-demand isr instead of regenerating on a certain interval we can actually trigger a regeneration on a certain event so instead of relying on the revalidate field here we can manually revalidate pages in api routes based on incoming requests for example we can listen to an incoming web hook from our data provider that tells us whenever new data has been added when we invoke the revalidate method the page on the specified path automatically gets regenerated another huge benefit of using on-demand isr instead of regular isr is the fact that the newly generated page is automatically distributed throughout the entire edge network with regular isr we only catch the response in the region where the user requests it from but with on-demand isr users from all over the world will always see cached content and they will never see a still page we also don't have to worry about unnecessarily invoking a service function every number of seconds if content hasn't been updated making it a much cheaper pattern to use all right so on demand isr gives us all the performance benefits combined with a great developer experience we don't have to worry about the high server cost anymore as long as we don't trigger a revalidation too often now static generation is an amazing pattern that can be used for tons of use cases we can have incredibly fast and dynamic websites and we also have a website that's always online because there's always a cached version available we also end up with way lower server costs or cost in general since we don't have to think about the server costs but there are also tons of use cases where static rendering isn't the best way to go for example for highly dynamic personalized pages in that case we want to use server side rendering so whereas he generated was or was the html was generated at build time using static rendering with server side rendering we actually create it on every request so this can be a great approach for pages that contain like highly personalized data or generally data that was within the request maybe user cookie it's also really good for pages that are vendor blocking may be based on authentication or authorization state an example of a highly dynamic page is anything that requires your uzi cookie for example this dashboard this dashboard is only shown when a user is authenticated and it shows user specific data so in next year as you can server render a page using the getservice.props method and this method runs on every request and the data that gets returned from this method is eventually passed to the generated html so when a user again requests a page the server side props method runs the page gets generated and sent to the client the client can quickly render this html and again can send an additional request to hydrate all the components now the generator pages are unique to every request meaning that they aren't automatically cached by our cdn although this is the expected behavior there is just more to take into consideration if you want to get or if you want to get a great performance for every request so when we look at the network and main thread it looks pretty similar to what we initially saw with static rendering the first contentful paints is equal to the largest contentful panes and we can easily avoid layout shifts as we're not dynamically rendering content but when we're comparing static rendering to server rendering you can see that the time to first byte can be very short when we statically render data whereas it can be pretty long when we server render data as we still have to generate the page on on demand now although server rendering is a great method when you want to like render highly personalized data there are just more to take into consideration to get a good performance we might also run into higher server costs which might be totally expected and worth it but there are a few things that you can do as a developer to optimize your ssr performance first we have to make sure that the getstaticprops method doesn't run for too long because the page generation won't start until this method has returned with data that gets passed to the page now one thing to keep in mind is that off or one thing to keep in mind is often also the cause of long acidic props execution is the time it takes to fetch data from your database so if your serverless function is deployed in san francisco but your database is deployed in tokyo it can take a while to establish a connection and actually get this data from here now instead consider moving your database to the same region as your serverless function to ensure that your database queries can be a lot faster next you might improve your performance a bit by adding caching headers to the responses but if you find yourself doing that your page might work even better if you used isr because besides not having to manually take care of revalidation the recomputed page will also be shared globally as opposed to just one single region izar also ensures that your website's always online and there's always a cached version available because with ssr you're dependent on the availability of the region because if your lambda is down so is your website um but yeah isr doesn't allow it to use request-based data so if you have a page that does require request-based data ssr is still the way to go now the last one is a bit harder to do as users namely upgrading your hardware so when you deploy to for cell we use serverless functions to server render your data and although serverless functions come with so many benefits there are some limitations to them now a common one is the cold boost and that's the time it takes to start the lambda also the slow connections to your database it's also not great to have to call a serverless function all the way and say the us west coast when you're located in europe or in asia now evercell we're currently exploring edge ssr which means that users can serve a render from all regions and experience a near-zero cold boot another huge benefit of edge ssr is the fact that the edge runtime also allows for http streaming with serverless functions we had to generate the entire page before a good gets sent to the client and then also download the entire bundle before hydration could start but with edges are we can actually stream parts of the document as sewn as they're ready and also hydrate them granularly so this means that users no longer have to see a blank screen for a long time as the components will stream them one by one streaming ssr also enables rex server components now i know it's already been talked about a little bit and i won't go into like the nitty-gritty details of react server components but the combination of edge ssr with react server components allow us to have a beautiful hybrid between static and server because react server components allow you to partially render your web components on the server which is especially useful for components that require or that use like really large dependencies because we no longer have to download them all the way on the client for example if we wanted to show this landing page again but this time we wanted to show like region specific listings to the user maybe with like a geolocation now the vast majority is still static it's just the listings that require request-based data so instead of having to server render the entire page we can now choose to only render the listings component server side and the rest still client side so whereas we initially had to server render the entire page to get this behavior we can now get the like great performance benefits of static combined with the dynamic benefits of ssr all right well we've just covered so many like patterns to choose from and i haven't even covered all of them but knowing which patterns makes the most sense for your application can give you huge performance benefits and with resell you can opt into these techniques on a per page basis making it extremely easy to scale without running into any performance issues when your application grows static and server rendering both have their place in the world and we're working on a future where we can create highly personalized pages with a great performance the web is extremely powerful and it's only getting better especially with an edge-first approach to look forward to thank you so much for coming to my talk you
Info
Channel: Real World React
Views: 48,165
Rating: undefined out of 5
Keywords:
Id: PN1HgvAOmi8
Channel Id: undefined
Length: 19min 49sec (1189 seconds)
Published: Tue May 24 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.