---
title: "Builds estáticos incrementales en Astro 7.2: cómo reduje mi tiempo de rebuild un 39%"
description: "Cómo los builds estáticos incrementales de Astro 7.2 redujeron el rebuild de un solo post de ~16.5s a ~10s, restaurando 637 de 661 páginas desde la caché con la configuración correcta de cacheKey."
source: "https://www.launchfa.st/es/blog/faster-astro-builds-incremental-static-builds"
author: "Rishi Raj Jain"
created_at: 2026-08-10T00:00:00.000Z
keywords: "astro, builds estáticos incrementales, incrementalBuild, cacheKey, getStaticPaths, astro 7.2, rendimiento de build, content collections, starlight, launchfast"
---

> **Site index for agents**
> Fetch https://www.launchfa.st/llms.txt to discover every page on this site.
> Every page is also available as Markdown by appending `.md` to its URL.

<div />

Reduje mi tiempo de rebuild incremental en aproximadamente un **39%**, de unos 16.5 segundos a unos 10, al habilitar los builds estáticos incrementales en [Astro 7.2](https://astro.build/blog/astro-720/).

Este sitio prerenderiza 661 páginas en cada build de producción: 70 posts de blog en tres idiomas, documentación, páginas de características y páginas de casos de uso. La mayoría de esas páginas no cambian entre despliegues. Antes de este cambio, editar un solo post seguía re-renderizando las 661.

Astro 7.2 permite que una ruta prerenderizada devuelva un `cacheKey` desde `getStaticPaths`. Astro restaura la página del build anterior cuando su grafo de módulos y esa clave permanecen sin cambios. Después de editar un solo post, 637 de 661 páginas se restauran desde la caché. Este post explica cómo lo configuré.

## Requisitos previos

- Astro 7.2 o posterior
- Rutas prerenderizadas (`export const prerender = true`)
- [Bun](https://bun.sh) para los pasos del patch de Starlight más abajo (npm/yarn/pnpm tienen herramientas de patch equivalentes)

## Paso 1: Habilita el flag

Para poder usar los builds incrementales, el primer paso es actualizar a 7.2 con el siguiente comando:

```bash
bun add astro@latest
```

Ten en cuenta que el modo es experimental. Actívalo en `astro.config.mjs` con el siguiente cambio:

```js
export default defineConfig({
  experimental: {
    incrementalBuild: true,
  },
})
```

Después de habilitar el flag, los dos primeros builds tardaron lo mismo. No se restauró ninguna página desde la caché. ¡Aquí entra la concurrencia!

## Paso 2: Corrige la configuración de concurrencia

Astro desactiva la caché incremental cuando las páginas se renderizan en paralelo:

```js
// node_modules/astro/dist/core/build/generate.js
if (options.settings.config.experimental.incrementalBuild) {
  if (options.settings.config.build.concurrency > 1) {
    logger.warn(
      'build',
      'The incremental build cache is disabled because `build.concurrency` is greater than 1.',
    )
  } else {
    // load the cache and restore pages
  }
}
```

Yo tenía `build.concurrency` configurado al número de CPUs. El renderizado en paralelo y la restauración de caché no funcionan juntos, así que eliminé mi override:

```js
// astro.config.mjs
// build: {
//   concurrency: Math.min(os.cpus().length, 12),   // removed
// }
```

Con la concurrencia de vuelta en el valor por defecto de `1`, pierdes el renderizado en paralelo pero ganas la restauración de caché. Ten en cuenta que esto solo ayuda si la mayor parte de tu sitio no cambia entre builds.

## Paso 3: Añade una cache key al blog

Una ruta se une a la caché devolviendo un `cacheKey` desde `getStaticPaths`. Astro reutiliza una página solo cuando su grafo de módulos y esta clave coinciden con el build anterior.

Las entradas de content collections tienen un `digest` que cambia cuando cambia el origen de la entrada:

```js
export async function getStaticPaths() {
  const posts = await getCollection('blog')
  return posts.map((post) => ({
    params: { slug: post.data.slug },
    props: { post },
    cacheKey: post.digest,
  }))
}
```

`post.digest` por sí solo no es suficiente para la plantilla de mi blog.

## Paso 4: Incluye todo lo que renderiza la página

Una página de blog aquí renderiza:

- Tres posts relacionados (vistas previas de título y descripción)
- El anuncio del patrocinador actual en la barra lateral

Ninguno forma parte de `post.digest`. Con solo el digest del post como clave, la caché sirve una página desactualizada cuando cambia un post relacionado o cambia la campaña del patrocinador.

```ts
// src/lib/cache-key.ts
import { getActiveSponsor } from '@/lib/sponsor'

type WithDigest = { digest?: string | number }

export function buildContentCacheKey(post: WithDigest, related: WithDigest[] = []): string {
  const sponsor = getActiveSponsor()?.id ?? 'none'
  const relatedDigests = related.map((entry) => entry.digest ?? '').join('.')
  return [post.digest ?? '', relatedDigests, sponsor].map(String).join('|')
}
```

El blog en los tres idiomas y las páginas de características usan esta clave. La caché se invalida cuando cambia el cuerpo del post, una vista previa relacionada o el patrocinador activo.

## Paso 5: Páginas de casos de uso

Las páginas de casos de uso son el grupo más grande del sitio: más de 300 entre todos los idiomas. No son entradas de content collections. Se generan a partir de TypeScript, una página por cada framework e integración.

Los datos son TypeScript importado, así que ya están en el grafo de módulos de la ruta. El hash de dependencias de Astro invalida cada página de caso de uso cuando cambian los datos, con o sin `cacheKey`. El grafo de módulos no cubre el anuncio del patrocinador, así que la clave solo necesita el slug y el patrocinador activo:

```ts
export function buildUseCaseCacheKey(useCase: { slug: string }, related: { slug: string }[] = []): string {
  const sponsor = getActiveSponsor()?.id ?? 'none'
  const relatedSlugs = related.map((entry) => entry.slug).join('.')
  return [useCase.slug, relatedSlugs, sponsor].join('|')
}
```

## Paso 6: Páginas de documentación (patch de Starlight)

La documentación funciona con [Starlight](https://starlight.astro.build), que inyecta una ruta catch-all `[...slug]`. No hay ningún `getStaticPaths` en mi código al que añadir una clave.

Primero intenté sombrear la ruta con `src/pages/[...slug].astro`. La documentación se restauró desde la caché, pero Astro registró un conflicto de rutas para cada ruta de documentación. Dos rutas reclamaban el mismo patrón.

La solución es aplicar un patch a la ruta inyectada por Starlight y hacerle seguimiento con `bun patch`:

```bash
bun patch @astrojs/starlight
# edit node_modules/@astrojs/starlight/routes/static/index.astro
bun patch --commit 'node_modules/@astrojs/starlight'
```

Esto escribe un patch en `patches/` y una entrada `patchedDependencies` en `package.json`. Bun lo reaplica en cada instalación:

```astro
---
// node_modules/@astrojs/starlight/routes/static/index.astro (patched)
import { paths } from '../../utils/routing';
import CommonPage from '../common.astro';
import { createHash } from 'node:crypto';

export const prerender = true;

export async function getStaticPaths() {
  const docsSetHash = createHash('sha1')
    .update(paths.map((p) => `${p.props?.entry?.id ?? ''}:${p.props?.entry?.digest ?? ''}`).sort().join('|'))
    .digest('hex');
  return paths.map((p) => ({ ...p, cacheKey: `${p.props?.entry?.digest ?? ''}|${docsSetHash}` }));
}
---
<CommonPage />
```

Cada página de documentación renderiza una barra lateral compartida y enlaces anterior/siguiente de todo el conjunto de documentación. La clave usa dos partes:

1. El digest de la entrada (el contenido de esta página)
2. Un hash sobre cada documento (barra lateral y paginación)

Si la documentación no cambió, las 96 páginas de documentación se restauran desde la caché.

## Resultados

Un build en frío completo frente a un rebuild incremental después de editar un solo post, con concurrencia 1:

| Build | Páginas restauradas | Tiempo total |
| --- | --- | --- |
| En frío (caché limpia) | 0 / 661 | ~16.5s |
| Incremental (un post editado) | 637 / 661 | ~10s |

Alrededor de un **39%** más rápido una vez que la caché está caliente. Editar un post re-renderiza 24 páginas, ese post más las páginas índice siempre dinámicas, y restaura las otras 637 🤯
