title | description | publishDate | authors | socialImage | coverImage | lang | |
---|---|---|---|---|---|---|---|
Unlock New Possibilities with Hybrid Rendering |
New in Astro 2.0: Hybrid rendering unlocks the best of both worlds—choose between the performance of static pages or the full flexibility of server rendering for each page of your website. |
January 26, 2023 |
|
/src/content/blog/_images/hybrid-rendering/social.webp |
/src/content/blog/_images/hybrid-rendering/cover.webp |
en |
import BlogContentImage from "/src/components/BlogContentImage.astro" // Images import staticBuild from "/src/content/blog/_images/hybrid-rendering/static.webp" import serverBuild from "/src/content/blog/_images/hybrid-rendering/server.webp" import hybridBuild from "/src/content/blog/_images/hybrid-rendering/hybrid.webp"
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.
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.
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.
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.
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.
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} />
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.
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!
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.
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.