Skip to content

Commit f728d23

Browse files
vicbkhuezyjames-elicxconico974
authored
docs(cloudflare): perf tips (#185)
Co-authored-by: khuezy <khuezy.nguyen@gmail.com> Co-authored-by: James Anderson <james@eli.cx> Co-authored-by: conico974 <nicodorseuil@yahoo.fr>
1 parent 2d5a308 commit f728d23

File tree

4 files changed

+113
-11
lines changed

4 files changed

+113
-11
lines changed

pages/cloudflare/_meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"caching": "",
77
"howtos": "How-Tos",
88
"examples": "",
9+
"perf": "Performance Tips",
910
"community": "Community projects",
1011
"known-issues": "Known issues",
1112
"troubleshooting": "",

pages/cloudflare/caching.mdx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,11 @@ import doQueue from "@opennextjs/cloudflare/overrides/queue/do-queue";
191191
import { purgeCache } from "@opennextjs/cloudflare/overrides/cache-purge/index";
192192

193193
export default defineCloudflareConfig({
194-
incrementalCache: withRegionalCache(r2IncrementalCache, { mode: "long-lived" }),
194+
incrementalCache: withRegionalCache(r2IncrementalCache, {
195+
mode: "long-lived",
196+
// Setting `bypassTagCacheOnCacheHit` to `true` requires enabling cache purge
197+
bypassTagCacheOnCacheHit: true,
198+
}),
195199
queue: doQueue,
196200
// This is only required if you use On-demand revalidation
197201
tagCache: doShardedTagCache({
@@ -264,7 +268,7 @@ Next.js also generates _immutable_ files that don't change between builds. Those
264268
There are 3 storage options for the incremental cache:
265269

266270
- **R2 Object Storage:** A [cost-effective](https://developers.cloudflare.com/r2/pricing/) S3-compatible object storage option for large amounts of unstructured data. Data is stored in a single region, meaning cache interactions may be slower - this can be mitigated with a regional cache.
267-
- **Workers KV:** A [fast](https://blog.cloudflare.com/faster-workers-kv) key value store, it uses Cloudflare's [Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) to increase cache hit rates. When you write cached data to Workers KV, you write to storage that can be read by any Cloudflare location. This means your app can fetch data, cache it in KV, and then subsequent requests anywhere around the world can read from this cache.
271+
- **Workers KV:** A [fast](https://blog.cloudflare.com/faster-workers-kv) key value store, it uses Cloudflare's [Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) to increase cache hit rates. When you write cached data to Workers KV, you write to storage that can be read by any Cloudflare location. This means your app can fetch data, cache it in KV, and then subsequent requests anywhere around the world can read from this cache. We do not recommend using KV because it is eventually consistent.
268272
- **Workers Static Assets:** A read-only store for the incremental cache, serving build-time values from [Workers Static Assets](https://developers.cloudflare.com/workers/static-assets/). Revalidation is not supported with this cache.
269273

270274
<Tabs items={["R2 Object Storage", "Workers KV", "Workers Static Assets"]}>
@@ -329,7 +333,7 @@ import { withRegionalCache } from "@opennextjs/cloudflare/overrides/incremental-
329333
export default defineCloudflareConfig({
330334
incrementalCache: withRegionalCache(r2IncrementalCache, {
331335
mode: "long-lived",
332-
shouldLazilyUpdateOnCacheHit: true,
336+
bypassTagCacheOnCacheHit: true,
333337
}),
334338
// ...
335339
});
@@ -751,3 +755,9 @@ If you want to use the durable object option, you will need to add the following
751755
```
752756

753757
You can customize the duration of the cache purge buffering with the `NEXT_CACHE_DO_PURGE_BUFFER_TIME_IN_SECONDS` environment variable. The default is 5 seconds. It works by buffering the purge requests for a given amount of time and then sending them all at once. This is useful to avoid hitting the API rate limits.
758+
759+
### Debugging
760+
761+
You can add `NEXT_PRIVATE_DEBUG_CACHE=1` to your app `.env` file to debug any cache issue.
762+
The app will output logs whenever the cache is accessed - those logs are generated by both Next and the cache adapter.
763+
You can find more details in [the Next documentation](https://nextjs.org/docs/app/guides/incremental-static-regeneration#verifying-correct-production-behavior)

pages/cloudflare/perf.mdx

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { Callout } from "nextra/components";
2+
3+
## Performance tips
4+
5+
They are a lot of features and knobs you can tune to improve the performance of your app. This page lists some of the recommend settings.
6+
7+
### General
8+
9+
You should regularly update to the latest available version of [`@opennextjs/cloudflare`](https://www.npmjs.com/package/@opennextjs/cloudflare) to benefit from the latest performance and security updates.
10+
11+
### Caching
12+
13+
Caching can drastically improves the performance of your application by only fetching data / re-generating your pages when they change.
14+
15+
To get the most out of caching, you should start by reading how Next.js implements caching. The ["Caching in Next.js" guide](https://nextjs.org/docs/app/guides/caching) is a good place to start.
16+
17+
You should then check [how to configure caching](/cloudflare/caching) for the OpenNext adapter. See below for some advice.
18+
19+
#### [Incremental Cache](/cloudflare/caching#incremental-static-regeneration-isr)
20+
21+
The Incremental cache is the store containing all the cached data (i.e. pages, `fetch`, `unstable_cache`).
22+
23+
You should use the Workers Static Assets based cache if your site is SSG. It is the fastest available option. Note that as Workers Static Assets are read-only, this option can not be used with revalidation.
24+
25+
When your app uses re-validation, use the R2 based store instead. We recommend the following settings to get the best perfomance:
26+
27+
- use regional cache by wrapping the handler into `withRegionalCache(...)`
28+
- use the `long-lived` mode
29+
- you should not need to explicitly set `shouldLazilyUpdateOnCacheHit` nor `bypassTagCacheOnCacheHit` as they are set to the most performant mode by default
30+
- setup [automatic cache purge](/cloudflare/caching#automatic-cache-purge)
31+
32+
<Callout type="info">
33+
Using KV is not recommended as it is eventually consistent. It could cause stale data to be persisted
34+
indefinitely
35+
</Callout>
36+
37+
#### [Tag Cache](/cloudflare/caching#tag-cache-for-on-demand-revalidation)
38+
39+
The Tag Cache is not properly a cache. It only stores the timestamp at which tags have been revalidated.
40+
41+
It should be configured for App-Router based app using `revalidateTag` or `revalidatePath`.
42+
43+
The D1 based tag cache should only be used if your site receives low traffic. The Durable Object based tag cache is the recommend option for most sites. See [the reference guide](/cloudflare/caching#tag-cache-for-on-demand-revalidation) for the available configuration options.
44+
45+
Application using `revalidateTag` exclusively (and not `revalidatePath`) will benefit from using the `withFilter` wrapper with the `softTagFilter` filter.
46+
47+
#### [Static Assets](/cloudflare/caching#static-assets-caching)
48+
49+
You should add a `public/_headers` file to cache the static assets served by your app.
50+
51+
See the [Cloudflare documentation](https://developers.cloudflare.com/workers/static-assets/headers/) for a detailed explanation of the default and the syntax.
52+
53+
### [Multiple Workers](https://opennext.js.org/cloudflare/howtos/multi-worker)
54+
55+
Deploying the middleware and the main server to distinct Workers can help with performance. As when a page can be retrieved from the cache, the main server can be fully bypassed.
56+
57+
### Troubleshooting performance
58+
59+
You can profile the code to troubleshoot performance issues.
60+
61+
#### Building unminified code
62+
63+
Code profiles are much easier to read when the code is not minified, you can use the following settings to generate unminified code
64+
65+
**next.config.ts**
66+
67+
```ts
68+
const nextConfig = {
69+
// ...
70+
experimental: {
71+
serverMinification: false,
72+
},
73+
webpack: (config) => {
74+
config.optimization.minimize = false;
75+
return config;
76+
},
77+
compress: false,
78+
};
79+
```
80+
81+
**CLI**
82+
83+
Use the `--noMinify` option when building the app:
84+
85+
```bash
86+
opennextjs-cloudflare build --noMinify
87+
```
88+
89+
#### Record a profile
90+
91+
You should first launch a local version of your application by running
92+
93+
```bash
94+
opennextjs-cloudflare preview
95+
```
96+
97+
Once the app is running, follow [the steps from the Workers doc](https://developers.cloudflare.com/workers/observability/dev-tools/cpu-usage/) to record a CPU profile.
98+
99+
You can then inspect the profile and check if any particular section of the application is unexpectedly slow.

pages/cloudflare/troubleshooting.mdx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,6 @@ import { Callout } from "nextra/components";
22

33
## Troubleshooting
44

5-
### Trying to deploy to Cloudflare Pages, instead of Cloudflare Workers?
6-
7-
`@opennextjs/cloudflare` is specifically built for deploying Next.js apps to [Cloudflare Workers](https://developers.cloudflare.com/workers/)
8-
9-
Cloudflare Workers now support the majority of functionality from Cloudflare Pages, and have features that are not yet supported by Cloudflare Pages. Refer to the [Compatibility Matrix](https://developers.cloudflare.com/workers/static-assets/compatibility-matrix/) in the Cloudflare Workers docs.
10-
11-
If you need to deploy to Cloudflare Pages, you can use `@cloudflare/next-on-pages`, and follow the [Cloudflare Pages guides for deploying Next.js apps](https://developers.cloudflare.com/pages/framework-guides/nextjs/).
12-
135
### "Your Worker exceeded the size limit of 3 MiB"
146

157
The Cloudflare Account you are deploying to is on the Workers Free plan, which [limits the size of each Worker to 3 MiB](https://developers.cloudflare.com/workers/platform/limits/#worker-size). When you subscribe to the Workers Paid plan, each Worker can be up to 10 MiB.

0 commit comments

Comments
 (0)