How Compado builds extremely fast media sites
Let’s get this right – What do we mean by fast? And what makes a website fast?
Do we mean low latency, that the site is extremely responsive, a low time to First Contentful Paint, optimal Time to Interactive, zero Total Blocking Time, low Largest Contentful Paint or in reality all of these simultaneously.
The most important thing to remember is that fast websites should feel fast to the user. This should be our end goal as developers. When a real user visits our site, it should feel responsive and fast to them.
What makes a website fast?
Going back to the original question. What makes a website fast?
The answer, like with most things, is that it kind of depends. There are many factors that contribute to both real and perceived performance, and you can spend hours or days focused on any one of them.
So, I’d like to simplify a bit and let’s look at website performance in terms of web experience.
In our case, a content/media site, where the primary reason for someone to visit is to read the content available there.
So we have :
- A permanent link
- Publicly accessible content
- Infrequently updated pages
- Reading is primary interaction
While new articles may be created regularly, once created they generally remain stable with few updates.
We focus on the essentials – we are not as concerned with being able to do other actions than just looking at the page, seeing what is on the page, and scrolling down to see more.
So, what can we do to make a media site fast?
Fundamentally, for content sites we must optimize for the first page load.
This is the ideal and common case when someone visits our website for the very first time. They don’t have anything in their browser cache for our site, and this changes how we need to optimize performance.
To ensure fast performance, we need to minimize round trips before the page gets painted. This is especially important in poor connectivity environments, as every round trip the browser has to make is just going to kill performance.
Finally, we need to ensure extremely low latency from the server. We must deliver content close to the user in order to ensure a minimal load time from when the user requests a page to when the page is sent back.
So what does a performant website look like?
I’d say, if this were the ‘90s, let’s go for it, but it’s 2023 and user expectations go a little bit further than default browser stylesheets.
What do we need to do to make a media site fast?
Let’s recap what we need to do to make a content site fast:
- Optimize for the first page load
- Minimize network round trips
- Minimize blocking style/scripts
- Minimize network latency
We can easily do the first three bullets when writing our site using Next.js.
But that’s not all.
To minimize network latency, however, we need to rely on an infrastructure built for exactly that.
Vercel provides such an infrastructure, and it relies on AWS as the provider.
We built our website use case using Next.js and frontend hosting from Vercel. To make it fast, we chose two approaches:
- static compilation
- incremental static regeneration (evented rendering).
Vercel and CDN
Vercel hosting serves the site as a static content from a global CDN (Content Delivery Network). It has an easy deploy and rollback system, as well as being able to redeploy at a page level, referred to as ISR (Incremental Static Regeneration). This means regenerating only the page that was updated, instead of regenerating the entire website.
When requests are made, Vercel will serve them from a global CDN. This is extremely straightforward and has the advantages of static sites. This is because there is zero request-time processing. You’re just serving flat files, so it can be incredibly fast. Additionally, it is also extremely cache efficient, because changes only happen when a new deploy or page regeneration is made. For page regeneration, Vercel will only invalidate the cache for one page, not the entire site.
There is literally not going to be a more performant way than doing a static site where you’re just serving flat files, and that’s what we are doing here.
What about dynamic rendering?
Dynamic rendering allows for fresh content to be instantly available. Since a request is made each time to render the page, we know that the content returned is always up to date.
Developers are also familiar with this architecture, as most have built request-response web servers in their time. However, it can be a bit inefficient and costly computationally, since the page is rendered every time a request is made, even when the content has not changed.
Caching dynamic content can be difficult due to the fact that we don’t always know when the content has changed. This creates a trade-off between serving stale content and incurring the penalty of having to re-render and compute.
In conclusion, I disagree with the idea of re-rendering a page on every request as it can be costly in terms of computational resources and can also serve up stale content if cached. It is better to optimize the page through caching so that the page is only rendered when necessary and the content is always fresh.
CDN’s are important
Using a CDN is critical for achieving top performance.
As such, we should prioritize rendering from CDNs to truly capitalize on the performance gains.
Vercel hosting is an excellent choice as it ensures that each time a website is served, the content is stored in the CDN and delivered from there for maximum benefit. This makes it the ideal way to take advantage of the speed and reliability that CDNs offer.
The ‘Holy Grail of Speed’ with Vercel
Benefits of using Next.js with Vercel:
- Render “expense” only paid once
- Fresh content available instantly
- Cache until content changes
- Serve only from CDN’s
Now, here’s how it works:
We deploy a site on Vercel, and Vercel generates a full static site. When data changes on one of the pages, that triggers a function that regenerates and revalidates that page.
This enables the content to change when the content changes, not every time it’s requested. We serve only static content from CDN on every request, and when the content changes, Vercel will invalidate the cache on the CDN only for that specific URL. This means we’ll have an indefinite server cache, resulting in CDN performance more often.
The benefits are clear. You still have fresh content available instantly, like with dynamic rendering, but we only pay the cost of rendering when the data changes, not when the user requests the site.
So, if my data changes once a day, then I’m only paying that cost once a day, instead of every time a user visits my site. We’re also caching until the content changes, and with the performance benefits of CDN’s, we get static-like performance even though we’re rendering content on demand and in an evented way.
Downside of serving Static Site and Incrementally static generation
The downside of serving a static site and incrementally static generation is that it may be unfamiliar territory. You need to think about what pages to regenerate when a page is changed.
For example, if you add a new blog post, you should regenerate the blog page, the category of the blog post, and the XML sitemap for the new page to appear.
But the end result will be an incredibly optimized and fast website.
To answer the original question: what makes a website fast?
The answer is you, the web developer.
Web experiences aren’t fast because of magic – they’re fast because developers care about performance and work hard to make it better.