-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add docs for experimental incremental static builds #14337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
1af3824
Add docs for experimental incremental static builds
matthewp 70693ba
Update src/content/docs/en/reference/experimental-flags/incremental-b…
matthewp 93e8325
Clarify incremental build cache persistence and add limitations
matthewp 42f0e11
Update src/content/docs/en/reference/experimental-flags/incremental-b…
matthewp 2e68a81
Update src/content/docs/en/reference/experimental-flags/incremental-b…
matthewp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
src/content/docs/en/reference/experimental-flags/incremental-build.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| --- | ||
| title: Experimental incremental static builds | ||
| sidebar: | ||
| label: Incremental builds | ||
| i18nReady: true | ||
| --- | ||
|
|
||
| import Since from '~/components/Since.astro' | ||
|
|
||
| <p> | ||
|
|
||
| **Type:** `boolean`<br /> | ||
| **Default:** `false`<br /> | ||
| <Since v="7.2.0" /> | ||
| </p> | ||
|
|
||
| This experimental feature reuses the output of a previous build so that unchanged pages are not rendered again. | ||
|
|
||
| When enabled, Astro can skip a static page generated by [`getStaticPaths()`](/en/reference/routing-reference/#getstaticpaths) if both its data and the code it depends on are unchanged since the last build. You mark a page's data by returning a `cacheKey` for it, and Astro tracks the code by hashing the page's module dependency graph. When both match the previous build, Astro copies the earlier output instead of rendering the page again. | ||
|
|
||
| On large sites where most pages change infrequently, this can reduce build times significantly because rendering is skipped for pages that would produce identical output. | ||
|
|
||
| To enable incremental builds, add the flag to your Astro config: | ||
|
|
||
| ```js title="astro.config.mjs" ins={5} | ||
| import { defineConfig } from "astro/config"; | ||
|
|
||
| export default defineConfig({ | ||
| experimental: { | ||
| incrementalBuild: true, | ||
| }, | ||
| }); | ||
| ``` | ||
|
|
||
| ## Providing a cache key | ||
|
|
||
| Only pages returned from `getStaticPaths()` that include a `cacheKey` can be skipped. Every other page, including static pages that do not use `getStaticPaths()`, is rendered on each build. | ||
|
|
||
| A `cacheKey` is a string that identifies the data used to render a page. Choose a value that changes whenever the page's content changes, such as a content hash, a version number, or an updated timestamp from your data source. Astro re-renders the page when its `cacheKey` differs from the previous build, and reuses the previous output when it is the same. | ||
|
|
||
| ```astro title="src/pages/blog/[slug].astro" | ||
| --- | ||
| export async function getStaticPaths() { | ||
| const posts = await fetchPosts(); | ||
|
|
||
| return posts.map((post) => ({ | ||
| params: { slug: post.slug }, | ||
| props: { post }, | ||
| cacheKey: post.updatedAt, | ||
| })); | ||
| } | ||
| --- | ||
| ``` | ||
|
|
||
| When you generate pages from a [content collection](/en/guides/content-collections/), a loader can provide a `digest` for each entry. The loader is responsible for updating this value whenever the entry's data changes. This makes it a convenient `cacheKey`: | ||
|
|
||
| ```astro title="src/pages/docs/[...slug].astro" | ||
| --- | ||
| import { getCollection, render } from "astro:content"; | ||
|
|
||
| export async function getStaticPaths() { | ||
| const entries = await getCollection("docs"); | ||
|
|
||
| return entries.map((entry) => ({ | ||
| params: { slug: entry.id }, | ||
| props: { entry }, | ||
| cacheKey: String(entry.digest), | ||
| })); | ||
| } | ||
|
|
||
| const { entry } = Astro.props; | ||
| const { Content } = await render(entry); | ||
| --- | ||
| ``` | ||
|
|
||
| ## How pages are invalidated | ||
|
|
||
| A page with a matching `cacheKey` is still re-rendered when the code it relies on changes. Astro hashes the page's module dependency graph, including the contents of its layouts, components, and imported files, so editing any of them invalidates the pages that use them. Changing your Astro configuration or your project's dependencies invalidates the entire cache, since those can affect the output of every page. | ||
|
|
||
| Pages that are removed from `getStaticPaths()` between builds have their previous output cleaned up automatically. | ||
|
|
||
| ## Preserving the cache between builds | ||
|
|
||
| Astro stores the incremental cache in your project's [`cacheDir`](/en/reference/configuration-reference/#cachedir), which is `node_modules/.astro/` by default. This holds both the build manifest and the reusable output of previously-rendered pages. The output directory is emptied at the start of every build, and skipped pages are restored from `cacheDir`. | ||
|
|
||
| For pages to be skipped in a continuous integration environment, `cacheDir` must be restored before running `astro build`. Cache and restore this single directory between builds; nothing else needs to persist. If it is missing, Astro re-renders every page. | ||
|
|
||
| To ignore the cache and re-render every page, run `astro build --force`. Astro still writes a fresh cache for the next build. | ||
|
|
||
| ## Limitations | ||
|
|
||
| This experimental feature currently has the following limitations: | ||
|
|
||
| - **`build.concurrency`**: The incremental cache is disabled when [`build.concurrency`](/en/reference/configuration-reference/#buildconcurrency) is greater than `1`. Astro logs a warning and re-renders every page. | ||
|
|
||
| - **Server islands**: A page that renders a [server island](/en/guides/server-islands/) embeds props encrypted with a key that is [regenerated on each build by default](/en/guides/server-islands/#reusing-the-encryption-key). Set a stable `ASTRO_KEY` so these pages can be reused between builds; without one, they are re-rendered every time. Changing the key also invalidates them, so their embedded content stays decryptable. | ||
|
matthewp marked this conversation as resolved.
Outdated
|
||
|
|
||
| - **Middleware**: Changes to your [middleware](/en/guides/middleware/) do not invalidate cached pages. If your middleware changes the HTML of prerendered pages, run `astro build --force` after editing it. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.