mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
The `DYNAMIC_EXPIRE` and `DYNAMIC_STALE` constants read as if the value itself is a dynamic expire or stale time, but every comparison is `expire < DYNAMIC_EXPIRE` / `stale < DYNAMIC_STALE`, so the value is the exclusive upper bound of the dynamic range: it is the smallest value that is *not* dynamic, not a dynamic value. The names are backwards at the boundary, which is easy to misread. The two thresholds also gate different things. `expire` gates whether a cache entry is included in the static prerender: below the threshold it becomes a dynamic hole, though a short-`expire` value is still served during a runtime prefetch. `stale` gates whether an entry is included in a runtime prefetch or app shell. This renames them to name that consequence: `MIN_PRERENDERABLE_EXPIRE` and `MIN_PREFETCHABLE_STALE`. It reads correctly both at the comparison sites (`expire < MIN_PRERENDERABLE_EXPIRE` is "below the minimum prerenderable expire", i.e. dynamic) and at the one site that uses the value directly, where private caches force `expire: MIN_PRERENDERABLE_EXPIRE` precisely because it is the shortest expire that stays prerenderable (and so is retained without being reclassified as a short-expire dynamic hole). This is a pure rename with no behavior change. --- <sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
35 lines
1.0 KiB
TypeScript
35 lines
1.0 KiB
TypeScript
import { cacheLife } from 'next/cache'
|
|
import { Suspense } from 'react'
|
|
|
|
async function getCachedRandom() {
|
|
'use cache'
|
|
// Long-lived (stale >= MIN_PREFETCHABLE_STALE, expire >=
|
|
// MIN_PRERENDERABLE_EXPIRE): stays in the static shell.
|
|
cacheLife({ stale: 60, revalidate: 100, expire: 1000 })
|
|
return Math.random()
|
|
}
|
|
|
|
async function ShortStaleCache() {
|
|
'use cache'
|
|
// Long expire (>= MIN_PRERENDERABLE_EXPIRE, 5min) and a non-zero revalidate,
|
|
// but a stale time below MIN_PREFETCHABLE_STALE (30s). This isolates the
|
|
// short-stale exclusion: the entry is omitted from the static shell purely
|
|
// because of its short stale time, not because of a short expire or
|
|
// revalidate: 0.
|
|
cacheLife({ stale: 18, revalidate: 100, expire: 1000 })
|
|
return <p id="y">{new Date().toISOString()}</p>
|
|
}
|
|
|
|
export default async function Page() {
|
|
const x = await getCachedRandom()
|
|
|
|
return (
|
|
<>
|
|
<p id="x">{x}</p>
|
|
<Suspense fallback={<p id="y">Loading...</p>}>
|
|
<ShortStaleCache />
|
|
</Suspense>
|
|
</>
|
|
)
|
|
}
|