Unlock New Possibilities with Hybrid Rendering

By
Nate Moore

Since the initial launch of Astro 1.0, developers have had to choose between generating static (SSG) or server (SSR) output. Static websites offer incredible performance by building your pages ahead-of-time. Servers leverage their dynamic power to generate HTML on-demand, unique for every request.

Until now, this had been an all-or-nothing decision—is this fully static or should I deploy a server?

Astro 2.0 unlocks the best of both worlds with hybrid rendering. Choose between the performance of static pages or the full flexibility of server rendering for each page of your website.

In this post, we’ll go over how hybrid rendering works by exploring just a few of the new features and performance improvements made possible in Astro 2.0.

How does Astro’s build process work?

Astro’s build process happens in multiple stages, beginning with a server-side JavaScript bundle generated by Vite. To simplify things a bit, the output of this bundle includes:

  • Server-side JavaScript used to render HTML
  • A client manifest which uses static analysis to collect all components needed for client-side interactivity
  • CSS and other assets for the client

Next, Astro uses the client manifest to initiate a second build process which bundles optimized client-side JavaScript.

If your configured output is static, Astro will execute the server-side JavaScript and write the output to .html files. The server-side JavaScript is then discarded.

Flow diagram of Astro's static build process

If your configured output is server, Astro passes the server-side JavaScript to an adapter for further processing. Adapters ensure that your server-side JavaScript is compatible with a particular hosting provider’s JavaScript runtime. Note that in this case, the final output is not a set of .html files, but the JavaScript code necessary to render HTML.

Flow diagram of Astro's server build process

Unfortunately, this setup was quite rigid and didn’t allow mixing static and dynamic routes in the same project. What we really needed was a process that enabled both patterns in parallel.

How does hybrid rendering work?

In Astro 2.0, we’ve revamped the astro build pipeline to handle hybrid rendering. During the initial bundling process, a new static analysis step determines which pages should be prerendered. This allows us to split your routes into seperate chunks, depending on when they should be rendered.

Much like the original static process, the prerendered chunk is executed and the output is written to .html files. The chunk is then discarded.

Much like the original server process, the server chunk is passed to an adapter for further processing. It will ultimately be deployed as a Serverless or Edge function, depending on your adapter.

Flow diagram of Astro's new hybrid build process

Why use static analysis?

Static analysis is a technique used to analyze your source code without actually executing it. Astro relies on this approach in many places, but it is especially critical during the build process. For performance reasons, Astro must be able to categorize your pages without executing their source code. For smaller projects, execution might not be a concern, but at scale it quickly becomes a bottleneck.

Hybrid rendering was specifically designed with static analysis in mind, though we did entertain alternative APIs. Astro’s build process is able to check for the presence of an export const prerender = true statement to determine which pages should be prerendered. To do this efficiently, we rely on the wonderful es-module-lexer library, which is also used internally in Node.

---
// This route should be generated at build time!
export const prerender = true
const text = await fetch("https://example.com/").then((res) => res.text())
---
<article set:html={text} />

Use cases for hybrid rendering

Hybrid rendering unlocks a whole new set of possible use cases, but we wanted to highlight a few that we’re particularly excited about.

Consider a small/medium e-commerce site built with Astro, with thousands of different possible products and variations. If you were to use static site generation, you’d be stuck rebuilding your website every time one of these products changed or went out of stock.

This kind of project calls for server-side rendering, which would allow your product pages to be generated fresh on every request. But now we have a new problem: your homepage is no longer static. Loading performance is still critical for driving sales, and your homepage doesn’t have any dynamic content that actually requires it to be rebuilt fresh on every request.

Hybrid rendering solves our performance problem by rendering the homepage to static HTML ahead-of-time, while keeping the rest of your website rendering on-demand.

Use case: add an API to your existing static site

As your static website grows, you may find the need to host a public API. Historically, adding an API to a static site has required host-specific configuration, but in Astro 2.0, we can add server endpoints (API routes) without sacrificing the performance of our static pages.

In fact, server endpoints can be added automatically by our Integrations API’s injectRoute hook. We’re excited to foster a powerful third-party integration ecosystem with these new primitives!

Use case: improve build performance of large sites

Static generation can be difficult to scale to thousands of pages, since every page must be rendered during the build process. Server-side rendering defers page rendering until request-time, removing a potential bottleneck from your build process.

When there are hundreds of routes generated by getStaticPaths, server-side rendering can lead to significant performance gains. In our internal testing, we saw build times improve by up to 30% by switching dynamic routes to server-side rendering.

Getting started with hybrid rendering

Hybrid rendering is available today in Astro 2.0! You can head to our server-side rendering guide to learn more about Astro’s SSR features. Astro’s official adapters have also been updated to support hybrid rendering, so be sure to install the latest version of your adapter.

To celebrate the launch, our friends at SST just launched astro-sst, their official AWS Adapter for Astro. Check out their announcement video & walkthrough to learn more and get started with AWS + SST.

We welcome your feedback! We collected some wonderful input during the Prerender API RFC and invite you to propose future ideas using our new public roadmap or Discord community.