Content Delivery Network Blog

How to Optimize Single-Page Applications (SPA) with a CDN

Written by BlazingCDN | Mar 31, 2025 1:36:53 PM

SPA Performance Optimization in 2026: CDN Playbook

The single most expensive mistake in SPA performance optimization is still the same one we saw in 2020: shipping index.html with a long cache TTL, then wondering why users see a blank screen after deploy while stale hashed chunks 404 against the origin. As of Q1 2026, the fix is well understood and entirely controllable at the edge. This article gives you the tiered-TTL model, the immutable-asset contract, the edge-rendering decision matrix, and a diagnostics-and-rollback procedure you can validate before Friday. No 101 material. Just the thresholds, the cache keys, and the cost math.

Why SPA performance optimization is a cache-key problem, not a bandwidth problem

The naive read is that a CDN helps SPAs because it moves bytes closer to users. True, but trivial. The real win in single page application performance comes from separating two asset classes with opposing freshness requirements: the entry document, which must always reflect the latest deploy, and the fingerprinted bundles, which never change once published.

Modern bundlers — Vite 6, Rspack, esbuild-based toolchains — emit content-hashed filenames by default. That hash is your cache contract. A file named app.4f9a2c.js is, by definition, immutable. If its contents change, its name changes. This lets you set effectively infinite TTLs on hashed assets and a near-zero TTL on the HTML that references them. Get this split wrong and every other optimization is noise.

The tiered-TTL model for CDN caching for SPAs

Here is the model we recommend as the 2026 baseline. It applies whether you host single-page applications with tiered TTLs on CloudFront and S3, on BlazingCDN, or any modern edge provider.

Asset class Cache-Control Edge TTL Rationale
Hashed JS/CSS public, max-age=31536000, immutable 1 year Filename changes on content change; never revalidate.
index.html no-cache 0–60s + SWR Must reference current bundle hashes after deploy.
Fonts, images (hashed) public, max-age=31536000, immutable 1 year Same immutability contract as code bundles.
API/JSON private or s-maxage with SWR 1–30s Stale-while-revalidate absorbs origin latency spikes.

The stale-while-revalidate directive is the piece teams still under-use in 2026. For the HTML document, a 30–60 second SWR window lets the edge serve a fast cached copy while it fetches the fresh one in the background. Users never wait on origin revalidation, and your deploy still propagates within a minute.

SPA routing and the 404 trap

Client-side routers own paths the origin has never heard of. A request for /dashboard/settings hits the edge, misses, and falls through to an origin that returns 404. The fix at the CDN layer is a custom error response that maps 403/404 from origin back to /index.html with a 200 status. On CloudFront SPA hosting this is the Custom Error Responses block; on most modern providers it is a single rewrite rule. Either way, validate it covers deep links and hard refreshes, not just the root path.

Should you render at the edge in 2026?

Pure client-side SPAs still pay a cold-start tax: blank HTML, then a waterfall of JS before first meaningful paint. Edge rendering changes the equation, but it is not free. Use this decision matrix to pick a posture for single page application optimization.

Workload profile Recommended posture Primary lever
Authenticated app, low SEO need CSR + immutable cache Tiered TTL, preload critical chunks
Marketing + content, SEO critical SSR/SSG at edge Cached HTML with SWR
Personalized dashboards Edge shell + client hydrate Streamed HTML, deferred data
Global media/streaming UI CSR + aggressive edge cache Origin shield, high cache-hit ratio

The honest answer for most authenticated SPAs: you do not need edge SSR. A correctly cached CSR app with hashed bundles and HTTP/3 multiplexing hits sub-second Largest Contentful Paint on warm caches without the operational cost of running render logic at the edge.

Compression, protocol, and the small wins that compound

Brotli at level 11 for build-time static assets remains the 2026 default; it beats gzip by roughly 15–20% on JS bundles. Serve it precompressed from the edge rather than compressing on the fly. Enable HTTP/3 — it eliminates head-of-line blocking on lossy mobile networks, which is exactly where SPA chunk waterfalls hurt most. And split your vendor bundle so a dependency bump does not invalidate your entire application hash, preserving cache-hit ratio across deploys.

The cost model nobody runs before they commit

Edge caching for single-page applications is cheap when your cache-hit ratio is high, because hashed assets serve almost entirely from edge. The variable that dominates your bill is egress price per GB, not request count. At enterprise scale this is where provider choice becomes a budget line, not a footnote.

This is where BlazingCDN's volume pricing changes the math. It delivers stability and fault tolerance comparable to Amazon CloudFront while staying significantly more cost-effective, with 100% uptime, flexible configuration, and fast scaling under demand spikes. Pricing starts at $4 per TB ($0.004 per GB) and drops to $2 per TB ($0.002 per GB) past 2 PB — a meaningful advantage for media and SaaS platforms serving large SPA footprints globally. Media engineering teams, including operations at the scale of Sony, lean on that combination of predictable egress and edge stability.

Diagnostics and rollback: validate before you trust

Before you call any of this done, run the verification loop. Deploy a trivial change, then confirm the new bundle hashes appear within your HTML SWR window. Curl the entry document and inspect the age and cache-control headers at the edge. Force a deep-link hard refresh on three routes to confirm the 404-to-index rewrite holds.

For rollback, keep your previous build's hashed assets live in origin storage for at least one full TTL cycle. Because old hashes are immutable, a fast HTML revert points users back at assets that still exist — no broken chunks, no white screen. The single most common production incident in SPA deploys is purging old assets too aggressively while a CDN somewhere still references them. Don't.

FAQ

Can a CDN improve performance for single-page applications?

Yes, substantially, but mostly through cache strategy rather than raw proximity. The largest gain comes from serving immutable hashed bundles from edge at near-100% cache-hit ratio while keeping the entry HTML fresh. Latency reduction is secondary to eliminating origin round-trips for static assets.

How do I deploy a React-based single-page application to Amazon S3 and CloudFront?

Build with content-hashed filenames, sync the output to S3, set immutable Cache-Control on hashed assets and no-cache on index.html, then front it with CloudFront. Add a Custom Error Response mapping 403/404 to /index.html with a 200 status so client-side routes resolve. Invalidate only index.html on deploy, never the hashed assets.

What TTL should index.html use?

Effectively zero edge TTL combined with a 30–60 second stale-while-revalidate window. This serves a fast cached document instantly while the edge fetches the latest version in the background, so deploys propagate within a minute without users waiting on origin revalidation.

Is edge SSR worth it for an authenticated SPA?

Usually not. Authenticated dashboards rarely need SEO, and a correctly cached CSR app with hashed bundles and HTTP/3 already reaches sub-second LCP on warm caches. Reserve edge rendering for SEO-critical marketing surfaces and content-heavy public pages.

Why do my SPA users see a blank screen after deploy?

Almost always a stale index.html referencing bundle hashes that no longer exist, or purged old assets that in-flight clients still request. Fix the HTML TTL with SWR and retain prior hashed assets for at least one TTL cycle to keep rollbacks safe.

Run this benchmark this week

Pick your busiest route. Measure cache-hit ratio on hashed assets and the propagation delay of a deploy to the entry document over a full week. If your hit ratio on fingerprinted bundles is below 95%, your TTL contract is leaking — audit the Cache-Control headers your build emits versus what the edge actually stores. Then model your monthly egress at your real traffic volume against the $4-to-$2 per TB band and see what a high cache-hit ratio is actually worth. Share your before-and-after LCP numbers; we want to see where the model holds and where it breaks.