Marketing page HTML served without edge caching forces every visit — including from users in the same CDN region as a previous visitor — to hit the origin server and wait for a full server-rendered response. With ISR or s-maxage cache headers, the CDN serves the pre-generated HTML directly from an edge node, making repeat visits within the cache window as fast as static file serving (TTFB under 50ms). ISO-25010 time-behaviour quality for HTML responses is identical to static assets when edge caching is configured. Marketing pages have no per-user dynamic content, making them ideal candidates for edge caching — yet Cache-Control: no-store or force-dynamic rendering defeats this capability entirely.
Info because edge caching for HTML is an enhancement over ISR that further reduces origin load and TTFB variance, but its absence is less severe than the underlying TTFB and CDN checks it depends on.
Add export const revalidate to marketing page route files to enable ISR — Vercel will cache the HTML at edge nodes and serve subsequent requests without hitting the origin.
// app/(marketing)/page.tsx
// Remove any: export const dynamic = 'force-dynamic'
// Cache for 1 hour; Vercel serves from edge on cache hit
export const revalidate = 3600
export default async function HomePage() {
const content = await getCMSContent() // fetched once per revalidate window
return <MarketingPage content={content} />
}
For custom hosting, set s-maxage to instruct CDN nodes to cache HTML:
export async function GET() {
return new Response(html, {
headers: {
'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400'
}
})
}
Verify caching is active by checking the x-vercel-cache or cf-cache-status response header — HIT confirms the CDN served from cache.
ID: marketing-page-speed.infrastructure.edge-caching-config
Severity: info
What to look for: HTML pages (as opposed to static assets) can also be cached at the CDN edge when their content is the same for all users. For ISR pages, the CDN caches the generated HTML and serves it without hitting the origin. Check: (1) Next.js revalidate exports on marketing page components, (2) Cache-Control headers with s-maxage (CDN cache duration), (3) Cloudflare Page Rules for HTML caching, (4) vercel.json for cache headers on HTML routes, (5) Fastly/Akamai VCL config files. Note: on Vercel, ISR pages are automatically cached at the edge — if revalidate is detected on the homepage, this is satisfied. Count all instances found and enumerate each.
Pass criteria: Marketing page HTML is cached at the CDN edge via ISR, s-maxage, or equivalent. Repeat visits (and first visits from same CDN region) are served from cache without an origin request. At least 1 implementation must be confirmed.
Fail criteria: All HTML is served from the origin with no CDN caching (Cache-Control: no-cache, no-store, or missing s-maxage). Every visit triggers an origin request.
Skip (N/A) when: Static export (output: 'export') — HTML files are already static and cached by the CDN as static assets.
Detail on fail: "Marketing pages use force-dynamic rendering with Cache-Control:no-store. Every visit hits the origin. With ISR (revalidate:3600), the CDN would serve cached HTML for 1 hour without origin load."
Remediation: Enable edge caching for marketing page HTML:
// Next.js App Router — ISR caches HTML at Vercel edge
// app/(marketing)/page.tsx
export const revalidate = 3600 // cache for 1 hour
// Or via response headers for custom hosting
export async function GET() {
return new Response(html, {
headers: {
'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400'
}
})
}