Web Development
Performance at Scale
Google's Core Web Vitals became a search ranking factor in 2021. A 100ms improvement in page load time correlates with a 1% increase in conversion rate for e-commerce (Google, 2017). Walmart found that every 1-second improvement in load time increased conversions by 2%. Performance is not an engineering vanity metric - it is a direct product outcome.
- Cloudflare serves content from 285+ edge locations globally. A static asset cached at the nearest edge location loads in ~10ms. The same asset served from a single-origin server in US-East adds 100-300ms of network latency for users in Asia or Europe.
- Vercel's Edge Network runs Next.js middleware in 70+ regions using the V8 isolate model (same as Cloudflare Workers). A geo-targeting middleware that personalizes content by country runs in <5ms at the edge without a round-trip to the origin.
- Shopify's storefront moved from client-side React to streaming SSR in 2023. Time to First Byte (TTFB) dropped from 800ms to 200ms, and Largest Contentful Paint (LCP) improved by 40% on mobile, directly increasing conversion rates on their highest-traffic storefronts.
Content Delivery Networks
A CDN is a distributed network of servers (Points of Presence - PoPs) positioned close to end users. Static assets (images, JavaScript bundles, CSS, fonts) are cached at the nearest PoP. The first request to a cold PoP fetches from the origin; subsequent requests are served from cache. Cache keys are typically the URL; Cache-Control headers determine TTL.
Content-hashing (fingerprinting) is the enabling technology for long-lived CDN caches. Webpack, Vite, and other bundlers append a content hash to each output filename. When source code changes, the hash changes, the URL changes, and the CDN fetches the new file. The old URL expires from cache naturally. No cache invalidation call needed.
Why do static JS bundles use `immutable` in Cache-Control while HTML documents use `no-cache`?
Edge Computing
Edge computing runs application logic at CDN PoPs, not at a central origin server. A Cloudflare Worker or Vercel Edge Function runs JavaScript (V8 isolate) in the region closest to the user. This eliminates the round-trip to the origin for operations like: A/B test bucketing, geo-based redirects, auth token verification, and personalized response headers. Cold start time is ~0ms (V8 isolates, not containers).
V8 isolates (Cloudflare Workers, Deno Deploy) start in under 5ms - orders of magnitude faster than Lambda cold starts (100-500ms). The trade-off: Workers have no file system, limited memory (~128 MB), and no native modules. Heavy computation still runs at the origin; lightweight request routing, auth, and A/B testing run at the edge.
Why do V8 isolate-based edge functions (Cloudflare Workers) start faster than Lambda functions?
Streaming SSR
Streaming SSR sends HTML to the browser in chunks rather than waiting for the entire page to render. The browser begins parsing and rendering the first chunk immediately - images load, fonts start, layout shifts are minimized - while the server is still rendering components that depend on slow data fetches. React 18's Suspense + renderToPipeableStream enables streaming; Next.js 13+ uses it by default.
TTFB (Time to First Byte) and LCP (Largest Contentful Paint) are the Core Web Vitals most affected by SSR strategy. With streaming, TTFB is the time to the first chunk (often < 50ms). The LCP element (hero image, headline) is included in the first chunk if architectured correctly, loading before slow data queries complete.
What does React Suspense enable in the context of streaming SSR?
Islands Architecture
Islands architecture renders the full page as static HTML on the server, then hydrates only the interactive components ("islands") on the client. The static parts - headers, footers, article text, product descriptions - ship as plain HTML with zero JavaScript. Only the shopping cart, search bar, and comment form load JavaScript for interactivity. Astro popularized this pattern; Qwik takes it further with resumability (no hydration at all).
Astro's hydration directives give granular control: client:load (immediate), client:idle (when browser is idle), client:visible (when island scrolls into view), client:media (when media query matches). These loading strategies reduce the JavaScript parsed and executed before the page is interactive - particularly impactful on mobile devices with slow CPUs.
More JavaScript on the page means a richer user experience and is always worth the performance cost
JavaScript is the most expensive browser resource per byte: it must be downloaded, parsed, compiled, and executed before it produces anything visible; every KB of JS is a cost paid by the user
A 100 KB image and a 100 KB JavaScript bundle have very different performance profiles. The image decodes once. The JS bundle blocks the main thread during parse and compile, delays interactivity, and can stall the browser on slow mobile CPUs. Islands architecture makes this cost explicit and minimizes it.
What distinguishes the Islands architecture from traditional SSR?
Key Ideas
- **CDN:** a globally distributed network of servers that caches static assets near users - the baseline optimization for every web application with global traffic
- **Edge computing:** running application logic at CDN edge locations (Cloudflare Workers, Vercel Edge Functions) to reduce latency for dynamic, personalized responses
- **Streaming SSR:** sending HTML to the browser in chunks as it is generated - the first chunk arrives before the entire page is ready, enabling early rendering and hydration
- **Islands architecture:** statically render the whole page, then hydrate only the interactive components ("islands") - the rest of the page is static HTML with no JavaScript
Related Topics
Performance sits across every layer of the stack:
- CDN and Caching — CDN serves the static output of Islands and streaming SSR - the two layers are complementary
- PWA and Service Workers — Service Worker caching extends CDN caching to the device level for repeat visits
- Architecture of Large Web Applications — Feature flags and A/B tests add edge compute to determine which variant to serve without origin round-trips
Вопросы для размышления
- CDN cache hit rates depend on traffic patterns. A long-tail e-commerce catalog with millions of unique product URLs mostly misses the CDN cache (low hit rate). What strategies transform a low-hit-rate dynamic system into a high-cache-rate one?
- Streaming SSR improves TTFB but requires the server to maintain an open connection for each streaming response. How does this affect server capacity planning compared to a traditional "generate full HTML, then send" SSR model?
- Islands architecture ships JavaScript only for interactive components. What happens when a "static" component needs to become interactive based on a user action that was not anticipated at build time?