Skip to content

Feat perf improvement #641

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 7 commits into from
May 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/lovely-rooms-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@opennextjs/cloudflare": patch
---

some performance improvements

- `enableCacheInterception` is now enabled by default, it loads ISR/SSG pages from cache without waiting for the js page bundle to load
- `routePreloadingBehavior` is now set to `withWaitUntil`, which means a single route js will be lazy loaded on cold start, but other routes will be preloaded using `waitUntil` for better performance
1 change: 1 addition & 0 deletions examples/e2e/app-pages-router/open-next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import memoryQueue from "@opennextjs/cloudflare/overrides/queue/memory-queue";
export default defineCloudflareConfig({
incrementalCache: r2IncrementalCache,
queue: memoryQueue,
enableCacheInterception: true,
});
12 changes: 9 additions & 3 deletions examples/e2e/app-router/e2e/isr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ test.describe("dynamicParams set to true", () => {
test("should be HIT on a path that was prebuilt", async ({ page }) => {
const res = await page.goto("/isr/dynamic-params-true/1");
expect(res?.status()).toEqual(200);
expect(res?.headers()["x-nextjs-cache"]).toEqual("HIT");
// TODO: sync this to aws
const cacheHeader = res?.headers()["x-nextjs-cache"] ?? res?.headers()["x-opennext-cache"];
expect(cacheHeader).toEqual("HIT");
const title = await page.getByTestId("title").textContent();
const content = await page.getByTestId("content").textContent();
expect(title).toEqual("Post 1");
Expand All @@ -115,7 +117,9 @@ test.describe("dynamicParams set to true", () => {
// We are gonna skip this one for now, turborepo caching can cause this page to be STALE once deployed
test.skip("should SSR on a path that was not prebuilt", async ({ page }) => {
const res = await page.goto("/isr/dynamic-params-true/11");
expect(res?.headers()["x-nextjs-cache"]).toEqual("MISS");
// TODO: sync this to aws
const cacheHeader = res?.headers()["x-nextjs-cache"] ?? res?.headers()["x-opennext-cache"];
expect(cacheHeader).toEqual("MISS");
const title = await page.getByTestId("title").textContent();
const content = await page.getByTestId("content").textContent();
expect(title).toEqual("Post 11");
Expand All @@ -140,7 +144,9 @@ test.describe("dynamicParams set to false", () => {
test("should be HIT on a path that was prebuilt", async ({ page }) => {
const res = await page.goto("/isr/dynamic-params-false/1");
expect(res?.status()).toEqual(200);
expect(res?.headers()["x-nextjs-cache"]).toEqual("HIT");
// TODO: sync this to aws
const cacheHeader = res?.headers()["x-nextjs-cache"] ?? res?.headers()["x-opennext-cache"];
expect(cacheHeader).toEqual("HIT");
const title = await page.getByTestId("title").textContent();
const content = await page.getByTestId("content").textContent();
expect(title).toEqual("Post 1");
Expand Down
1 change: 1 addition & 0 deletions examples/e2e/app-router/open-next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export default defineCloudflareConfig({
},
}),
queue: doQueue,
enableCacheInterception: true,
});
1 change: 1 addition & 0 deletions examples/playground14/open-next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cac

export default defineCloudflareConfig({
incrementalCache: kvIncrementalCache,
enableCacheInterception: true,
});
1 change: 1 addition & 0 deletions examples/playground15/open-next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cac

export default defineCloudflareConfig({
incrementalCache: kvIncrementalCache,
enableCacheInterception: true,
});
13 changes: 12 additions & 1 deletion packages/cloudflare/src/api/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ export type CloudflareOverrides = {
* Sets the revalidation queue implementation
*/
queue?: "direct" | Override<Queue>;

/**
* Enable cache interception
* Should be `false` when PPR is used
* @default false
*/
enableCacheInterception?: boolean;
};

/**
Expand All @@ -37,7 +44,7 @@ export type CloudflareOverrides = {
* @returns the OpenNext configuration object
*/
export function defineCloudflareConfig(config: CloudflareOverrides = {}): OpenNextConfig {
const { incrementalCache, tagCache, queue } = config;
const { incrementalCache, tagCache, queue, enableCacheInterception = false } = config;

return {
default: {
Expand All @@ -49,12 +56,16 @@ export function defineCloudflareConfig(config: CloudflareOverrides = {}): OpenNe
tagCache: resolveTagCache(tagCache),
queue: resolveQueue(queue),
},
routePreloadingBehavior: "withWaitUntil",
},
// node:crypto is used to compute cache keys
edgeExternals: ["node:crypto"],
cloudflare: {
useWorkerdCondition: true,
},
dangerous: {
enableCacheInterception,
},
};
}

Expand Down