How the Right Architecture For Your Use Case Impacts Performance — Transcript

Transcript of the free Vue.js lesson How the Right Architecture For Your Use Case Impacts Performancewatch the video lesson.

Choosing the right architecture for your view application can be a big step in keeping things fast. In this lesson, let's explore different rendering strategies and help you make the right choice for your specific use case. Let's start with client-side rendering, or what we often call a single-page application. A lot of times, this is referred to as SPA for short.

Here's how it works. First, your browser sends a request. to the server, and then the server sends back a minimal HTML shell. That HTML shell doesn't have any content in it, it's just a placeholder for where your view app will mount once it's ready to.

Then the JavaScript downloads that contains your view application, and that JavaScript executes, which bootstraps view and renders your content to the page. This is absolutely great for applications that are highly interactive and need a lot of browser-side JavaScript. But of course, they have their trade-offs. Number one, search engines might struggle to index them quickly.

More importantly for this course, initial load times can be slower as the user has to wait for the entire JavaScript bundle to download, parse, and execute. Social media preview cards won't work. and the performance totally depends on the user's device, as everything is rendered on the client's side, right? JavaScript is doing the heavy lifting directly on the user's device.

Therefore, practically speaking, SPAs are perfect for things like admin dashboards, highly interactive applications, apps where users spend long sessions, things like project management tools, things like that. but not marketing sites or content sites where page load speed is a top priority. Basically shipping JavaScript no matter what is always going to be slower than shipping just plain HTML. So when speed is a top priority and you don't have a lot of interactivity, you should probably skip the SPA approach.

Now let's look at server side rendering or SSR for short. Instead of sending an empty shell, This time the server generates complete HTML for each request, meaning that the page will display its contents immediately without having to wait for any JavaScript to load. Let's break that down step by step, just like we did with the SPA. Here's how it works.

First, the browser requests the page from the server, and the server sends back fully rendered HTML. All the DOM elements are there, all the HTML already exists, the user can see something as soon as the server responds. querySelector and so on. Like SPAs though, server-side rendered apps also have their trade-offs.

Hosting costs more as you'll use processing power on the server-side to render the pages, and it's not ideal for highly interactive features as most of the logic is done on the server. For content-driven sites, though, SSRs are awesome. They're great for content-heavy sites with dynamic data, pages where SEO is crucial, sites targeting users with slower devices, since you don't have to run any JavaScript on their device to render the page, and sites that don't require much interactivity. Server-side rendering things is going to be one of the fastest approaches especially over and above an SPA.

Next up is Universal Rendering. This is where things get really interesting because Universal Rendering combines both of the approaches we saw before. This time, the server sends complete HTML and then view hydrates it on the client side with JavaScript to make it interactive. Here's a breakdown of how it works.

First, the browser requests your page from the server. the server sends back the fully rendered HTML to the browser, but then also request a JavaScript bundle, which is downloaded and executed, at which point, Vue bootstraps the app and then hydrates the static HTML in order to make it interactive. You can kind of imagine hydration as this overlay of the JavaScript app overlaying the static HTML. This gives us the best of both worlds.

The page is immediately viewable, but then we can add more interactive elements as the JavaScript loads and hydrates that static HTML. Of course, for regular content pages, which don't really need any additional interactivity, this is still overkill and not necessary. You'd be better off shipping zero JavaScript for that period. Okay, what about the next?

option. Well, next up we have a slight variation of universal rendering called static site generation or SSG for short. Instead of generating HTML for each request, we pre-build everything during deployment. This is the process.

During build time or deploy time, we generate the HTML for every page on our site. Then we store those HTML files on our server as static HTML files. When the browser then requests a particular page, the server can serve that static HTML file instantly as there's no processing to be done. At that point, the user sees the page content immediately, and for a content-driven site, you don't have to do any hydration.

For more interactive sites, you're free to hydrate it and make it interactive, just like you do with universal rendering. SSG is Perfect for a lot of things, actually. It's great for documentation sites, it's great for marketing pages, it's great for blogs, any content that rarely changes and is the same per user, per route. It's literally the fastest way to do things, but it does come with a few complications as your site content can only be customized at deploy time instead of at request time.

Okay, that leads us to the final rendering strategy. Just like universal rendering mixes SSR and SPA in terms of where the app is rendered, incremental static generation, or ISG for short, is a mix of SSG and SSR in terms of when the app is rendered. In my opinion, it's basically a glorified cache, but it's really super powerful. The caching strategy used by ISG is known as SWR or stale while revalidate.

The flow looks like this. On the first request of a page from the browser, the server renders it, but then it also caches the rendered HTML. All subsequent requests for a specified time period will say two minutes, receive the cached HTML, and the server does no processing. After the two minutes is up, The server still sends the cached HTML, but in the background re-renders the page and stores the fresh version in the cache.

At that point, subsequent requests go back to the cache again, and this process loops indefinitely. This gives us the same speed of the server response as SSG does, but it allows us to do some more dynamic things with our content as universal rendering does. All of these different approaches have their pros and cons, but the beauty of developing with Vue is that we can actually mix and match these different approaches within a single app with the power of Nuxt. It supports defining different rendering modes per route or per page of our application, and even sometimes gives you the opportunity to pick at the component level.

Since we already have a video on the Vue School website, showing you exactly how to do this with route rules, then I'll just point you over to that video in the description below, and you can watch further there if you're interested. The takeaway for this video is that you should know the different options that you're dealing with. For any content that's just meant to be read, just static content that doesn't have any interactivity, avoid sending any JavaScript at all. Downloading and executing that JavaScript is always going to take more time than going without it.

For pages that do need more interactivity, consider using the universal approach so that the user sees something very quickly, the static HTML, but can then interact with the interactive elements soon after.