From cd134843c85b4a3b7e368fa541788a12ffb5c50f Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Fri, 10 Oct 2025 10:51:05 -0400 Subject: [PATCH 1/2] improve withCloudflare() execution cost --- .changeset/chilly-pens-tease.md | 5 ++ .../overrides/originResolver/pattern-env.ts | 81 ++++++++++++++----- 2 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 .changeset/chilly-pens-tease.md diff --git a/.changeset/chilly-pens-tease.md b/.changeset/chilly-pens-tease.md new file mode 100644 index 000000000..f2e164ea4 --- /dev/null +++ b/.changeset/chilly-pens-tease.md @@ -0,0 +1,5 @@ +--- +"@opennextjs/aws": patch +--- + +Improve withCloudflare() execution cost by caching internals diff --git a/packages/open-next/src/overrides/originResolver/pattern-env.ts b/packages/open-next/src/overrides/originResolver/pattern-env.ts index 24308c59a..e33225a46 100644 --- a/packages/open-next/src/overrides/originResolver/pattern-env.ts +++ b/packages/open-next/src/overrides/originResolver/pattern-env.ts @@ -3,34 +3,71 @@ import type { OriginResolver } from "types/overrides"; import { debug, error } from "../../adapters/logger"; +// Cache parsed origin and compiled patterns at module level +let cachedOrigin: Record | null = null; +const cachedPatterns: Array<{ + key: string; + patterns: string[]; + regexes: RegExp[]; +}> = []; +let initialized = false; + +function initialize() { + if (initialized) return; + + // Parse origin JSON once + cachedOrigin = JSON.parse(process.env.OPEN_NEXT_ORIGIN ?? "{}") as Record< + string, + Origin + >; + + // Pre-compile all regex patterns + const functions = globalThis.openNextConfig.functions ?? {}; + for (const key in functions) { + if (key !== "default") { + const value = functions[key]; + const regexes: RegExp[] = []; + + for (const pattern of value.patterns) { + // Convert cloudfront pattern to regex + const regexPattern = `/${pattern + .replace(/\*\*/g, "(.*)") + .replace(/\*/g, "([^/]*)") + .replace(/\//g, "\\/") + .replace(/\?/g, ".")}`; + regexes.push(new RegExp(regexPattern)); + } + + cachedPatterns.push({ + key, + patterns: value.patterns, + regexes, + }); + } + } + + initialized = true; +} + const envLoader: OriginResolver = { name: "env", resolve: async (_path: string) => { try { - const origin = JSON.parse(process.env.OPEN_NEXT_ORIGIN ?? "{}") as Record< - string, - Origin - >; - for (const [key, value] of Object.entries( - globalThis.openNextConfig.functions ?? {}, - ).filter(([key]) => key !== "default")) { - if ( - value.patterns.some((pattern) => { - // Convert cloudfront pattern to regex - return new RegExp( - // transform glob pattern to regex - `/${pattern - .replace(/\*\*/g, "(.*)") - .replace(/\*/g, "([^/]*)") - .replace(/\//g, "\\/") - .replace(/\?/g, ".")}`, - ).test(_path); - }) - ) { - debug("Using origin", key, value.patterns); - return origin[key]; + initialize(); + + // Use cached origin + const origin = cachedOrigin!; + + // Test against pre-compiled patterns + for (const { key, patterns, regexes } of cachedPatterns) { + for (const regex of regexes) { + if (regex.test(_path)) { + debug("Using origin", key, patterns); + return origin[key]; + } } } + if (_path.startsWith("/_next/image") && origin.imageOptimizer) { debug("Using origin", "imageOptimizer", _path); return origin.imageOptimizer; From da3a4cca9db1653f2569ae4d6a900296a591a974 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Fri, 10 Oct 2025 17:54:17 +0200 Subject: [PATCH 2/2] fixup! misc minor edits --- .changeset/chilly-pens-tease.md | 2 +- .../overrides/originResolver/pattern-env.ts | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.changeset/chilly-pens-tease.md b/.changeset/chilly-pens-tease.md index f2e164ea4..dec21d6ed 100644 --- a/.changeset/chilly-pens-tease.md +++ b/.changeset/chilly-pens-tease.md @@ -2,4 +2,4 @@ "@opennextjs/aws": patch --- -Improve withCloudflare() execution cost by caching internals +perf(OriginResolver): cache expensive compute diff --git a/packages/open-next/src/overrides/originResolver/pattern-env.ts b/packages/open-next/src/overrides/originResolver/pattern-env.ts index e33225a46..8f9b59ebf 100644 --- a/packages/open-next/src/overrides/originResolver/pattern-env.ts +++ b/packages/open-next/src/overrides/originResolver/pattern-env.ts @@ -3,8 +3,8 @@ import type { OriginResolver } from "types/overrides"; import { debug, error } from "../../adapters/logger"; -// Cache parsed origin and compiled patterns at module level -let cachedOrigin: Record | null = null; +// Cache parsed origins and compiled patterns at module level +let cachedOrigins: Record; const cachedPatterns: Array<{ key: string; patterns: string[]; @@ -12,11 +12,14 @@ const cachedPatterns: Array<{ }> = []; let initialized = false; -function initialize() { +/** + * Initializes the cached values on the first execution + */ +function initializeOnce(): void { if (initialized) return; // Parse origin JSON once - cachedOrigin = JSON.parse(process.env.OPEN_NEXT_ORIGIN ?? "{}") as Record< + cachedOrigins = JSON.parse(process.env.OPEN_NEXT_ORIGIN ?? "{}") as Record< string, Origin >; @@ -53,28 +56,25 @@ const envLoader: OriginResolver = { name: "env", resolve: async (_path: string) => { try { - initialize(); - - // Use cached origin - const origin = cachedOrigin!; + initializeOnce(); // Test against pre-compiled patterns for (const { key, patterns, regexes } of cachedPatterns) { for (const regex of regexes) { if (regex.test(_path)) { debug("Using origin", key, patterns); - return origin[key]; + return cachedOrigins[key]; } } } - if (_path.startsWith("/_next/image") && origin.imageOptimizer) { + if (_path.startsWith("/_next/image") && cachedOrigins.imageOptimizer) { debug("Using origin", "imageOptimizer", _path); - return origin.imageOptimizer; + return cachedOrigins.imageOptimizer; } - if (origin.default) { - debug("Using default origin", origin.default, _path); - return origin.default; + if (cachedOrigins.default) { + debug("Using default origin", cachedOrigins.default, _path); + return cachedOrigins.default; } return false as const; } catch (e) {