From 2e11396e451d26aa5ae4987ac26aebaa4a1694e5 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Wed, 31 Dec 2025 12:10:21 -0500 Subject: [PATCH 1/5] Filter routes by environment and fix image loading Reduces memory by having each environment only build the pages it needs: - SSR: only on-demand rendered pages (prerender: false) - Prerender: only static pages (prerender: true) Fix image loading to use .prerender/ subdirectory where assets are emitted. --- packages/astro/src/assets/build/generate.ts | 3 ++- packages/astro/src/vite-plugin-pages/pages.ts | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/astro/src/assets/build/generate.ts b/packages/astro/src/assets/build/generate.ts index 76fa66e5a2fa..a7e798057f3f 100644 --- a/packages/astro/src/assets/build/generate.ts +++ b/packages/astro/src/assets/build/generate.ts @@ -74,7 +74,8 @@ export async function prepareAssetsGenerationEnv( const isServerOutput = settings.buildOutput === 'server'; let serverRoot: URL, clientRoot: URL; if (isServerOutput) { - serverRoot = manifest.buildServerDir; + // Images are collected during prerender, which outputs to .prerender/ subdirectory + serverRoot = new URL('.prerender/', manifest.buildServerDir); clientRoot = manifest.buildClientDir; } else { serverRoot = getOutDirWithinCwd(manifest.outDir); diff --git a/packages/astro/src/vite-plugin-pages/pages.ts b/packages/astro/src/vite-plugin-pages/pages.ts index 3e0716a03698..cf52911da33f 100644 --- a/packages/astro/src/vite-plugin-pages/pages.ts +++ b/packages/astro/src/vite-plugin-pages/pages.ts @@ -40,7 +40,20 @@ export function pluginPages({ routesList }: PagesPluginOptions): VitePlugin { const pageMap: string[] = []; let i = 0; - for (const route of routesList.routes) { + // Filter routes based on the build environment to reduce memory usage. + // Each environment only builds the pages it needs: + // - SSR environment: builds only on-demand rendered pages (prerender: false) + // - Prerender environment: builds only static pages (prerender: true) + // - Other environments (e.g. client): get all routes + const envName = this.environment.name; + const isSSR = envName === ASTRO_VITE_ENVIRONMENT_NAMES.ssr; + const isPrerender = envName === ASTRO_VITE_ENVIRONMENT_NAMES.prerender; + const routes = + isSSR || isPrerender + ? routesList.routes.filter((route) => route.prerender === isPrerender) + : routesList.routes; + + for (const route of routes) { if (routeIsRedirect(route)) { continue; } From 68e094c2022212f9d56a5dbda3f08b0a21bf0b79 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Wed, 31 Dec 2025 12:12:26 -0500 Subject: [PATCH 2/5] changeset --- .changeset/memory-route-filter.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/memory-route-filter.md diff --git a/.changeset/memory-route-filter.md b/.changeset/memory-route-filter.md new file mode 100644 index 000000000000..821f3b825ba1 --- /dev/null +++ b/.changeset/memory-route-filter.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Reduces build memory by filtering routes per environment so each only builds the pages it needs From a7ed4dc54917f1354616d2830e90dbc4ef02fb38 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Wed, 31 Dec 2025 13:49:10 -0500 Subject: [PATCH 3/5] add next as target --- .github/workflows/preview-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview-release.yml b/.github/workflows/preview-release.yml index 873b1e222335..e7471e6b2040 100644 --- a/.github/workflows/preview-release.yml +++ b/.github/workflows/preview-release.yml @@ -2,7 +2,7 @@ name: Preview release on: pull_request: - branches: [main] + branches: [main, next] types: [labeled] concurrency: From 5db6c74cc7abaae8316b42a0894aaf7ebc6d158a Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Fri, 2 Jan 2026 09:25:13 -0500 Subject: [PATCH 4/5] fix: use manifest.buildClientDir in test adapter --- packages/astro/test/test-adapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/astro/test/test-adapter.js b/packages/astro/test/test-adapter.js index 7616ff0fb587..ff49295ba09c 100644 --- a/packages/astro/test/test-adapter.js +++ b/packages/astro/test/test-adapter.js @@ -85,7 +85,7 @@ export default function ({ async render(request, { routeData, clientAddress, locals, addCookieHeader, prerenderedErrorPageFetch } = {}) { const url = new URL(request.url); if(this.#manifest.assets.has(url.pathname)) { - const filePath = new URL('../../client/' + this.removeBase(url.pathname), import.meta.url); + const filePath = new URL(this.removeBase(url.pathname).replace(/^\\//, ''), this.#manifest.buildClientDir); const data = await fs.promises.readFile(filePath); return new Response(data); } From cb95536ef60d44858c5d90da0b2dd3b81cab89ad Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Fri, 2 Jan 2026 11:44:17 -0500 Subject: [PATCH 5/5] fix: include redirectRoute in environment route filtering --- packages/astro/src/vite-plugin-pages/pages.ts | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/astro/src/vite-plugin-pages/pages.ts b/packages/astro/src/vite-plugin-pages/pages.ts index cf52911da33f..a7ea68ae51db 100644 --- a/packages/astro/src/vite-plugin-pages/pages.ts +++ b/packages/astro/src/vite-plugin-pages/pages.ts @@ -2,6 +2,7 @@ import type { Plugin as VitePlugin } from 'vite'; import { DEFAULT_COMPONENTS } from '../core/routing/default.js'; import { routeIsRedirect } from '../core/routing/index.js'; import type { RoutesList } from '../types/astro.js'; +import type { RouteData } from '../types/public/internal.js'; import { VIRTUAL_PAGE_MODULE_ID } from './const.js'; import { getVirtualModulePageName } from './util.js'; import { ASTRO_VITE_ENVIRONMENT_NAMES } from '../core/constants.js'; @@ -13,6 +14,23 @@ interface PagesPluginOptions { routesList: RoutesList; } +/** + * Filters routes for a specific build environment. + * Redirects need their target route included so the redirect response can be generated at runtime. + */ +function getRoutesForEnvironment(routes: RouteData[], isPrerender: boolean): Set { + const result = new Set(); + for (const route of routes) { + if (route.prerender === isPrerender) { + result.add(route); + } + if (route.redirectRoute) { + result.add(route.redirectRoute); + } + } + return result; +} + export function pluginPages({ routesList }: PagesPluginOptions): VitePlugin { return { name: '@astro/plugin-pages', @@ -50,8 +68,8 @@ export function pluginPages({ routesList }: PagesPluginOptions): VitePlugin { const isPrerender = envName === ASTRO_VITE_ENVIRONMENT_NAMES.prerender; const routes = isSSR || isPrerender - ? routesList.routes.filter((route) => route.prerender === isPrerender) - : routesList.routes; + ? getRoutesForEnvironment(routesList.routes, isPrerender) + : new Set(routesList.routes); for (const route of routes) { if (routeIsRedirect(route)) {