Static Site Generation: Maximum Performance Through Pre-rendering
Static site generation produces the fastest possible web pages by eliminating server-side computation at request time. Every page is pre-rendered during the build process, resulting in HTML files that can be served directly from a CDN edge node without any application server, database query, or template rendering. The result is Time to First Byte measured in single-digit milliseconds from the nearest edge location, Largest Contentful Paint that consistently beats dynamic alternatives, and infrastructure costs that approach zero at scale.
How Static Generation Achieves Peak Performance
The performance advantage of static generation comes from eliminating everything between the CDN cache and the HTML response. A dynamic site processes each request through a chain: DNS resolution, TCP connection, TLS handshake, load balancer routing, application server processing, database queries, template rendering, and response serialization. A static site shortcuts this chain — the pre-rendered HTML sits on the CDN, and the response is the file itself.
This architectural difference produces measurable performance gains across every metric. TTFB drops from hundreds of milliseconds to single digits when served from a nearby edge node. Server response time effectively becomes network latency because there is no computation to perform. Cache hit ratios approach 100 percent because every page is a static file — there are no cache-busting query parameters, no user-specific headers, and no session state.
Build-Time Rendering Architecture
Static generators execute during the build phase, fetching data from APIs, databases, files, and headless CMS platforms, then rendering every page as a standalone HTML file. The build output is a directory of HTML, CSS, JavaScript, and asset files that any web server or CDN can serve without special runtime requirements.
Data Fetching at Build Time
Build-time data fetching aggregates content from multiple sources into a unified data layer. A typical static site might pull article content from a headless CMS, navigation structure from a configuration file, author profiles from a database, and product data from an API. The build process resolves all of these dependencies, processes the data through templates, and outputs complete HTML.
Key considerations for build-time data fetching:
- Source reliability: Build failures cascade from data source outages. Implement fallback strategies — cached copies of the last successful response, default values for non-critical data, partial builds that skip failed pages.
- Data freshness: Build-time data is frozen at the moment of the build. Content updated after the build does not appear until the next build completes. This is the fundamental tradeoff of static generation — performance comes at the cost of real-time data accuracy.
- Build parallelism: Data fetching is often the slowest part of the build. Parallelize independent data source calls and cache responses across builds to reduce build times.
Build Performance at Scale
As page count grows, build times grow proportionally. A site with 10,000 pages may take 20 to 60 minutes to build, making frequent rebuilds impractical. Several strategies address build time at scale:
| Strategy | Mechanism | Build Time Reduction |
|---|---|---|
| Incremental builds | Rebuild only changed pages and their dependents | 80–95% |
| Distributed builds | Split page generation across multiple workers | 60–80% |
| Content-based caching | Cache rendered output by content hash | 70–90% |
| On-demand generation | Build pages on first request (ISR/DPR) | Variable |
Incremental Static Regeneration
Incremental Static Regeneration (ISR) combines static generation with on-demand updates. Pages are statically generated at build time and served from cache, but they can be regenerated in the background when the cached version exceeds a specified age. This addresses the fundamental freshness limitation of pure static generation without sacrificing its performance advantages.
Time-Based Revalidation
Time-based ISR assigns a revalidation interval to each page. When a request arrives for a page whose cached version is older than the interval, the server serves the stale version immediately (maintaining fast response times) and triggers a background regeneration. The next request receives the fresh version.
Choosing revalidation intervals requires balancing freshness against build cost:
- News and feeds: 60 to 300 seconds. Content changes frequently and staleness is immediately visible to users.
- Product pages: 300 to 3,600 seconds. Price and availability changes matter but are not second-by-second critical.
- Documentation and guides: 3,600 to 86,400 seconds. Content changes infrequently and staleness is rarely noticed.
- Marketing and landing pages: 86,400 seconds or longer. Content changes on editorial schedules, not real-time events.
On-Demand Revalidation
On-demand revalidation triggers page regeneration through an API call rather than a timer. When content changes in the CMS, a webhook triggers regeneration of the affected pages. This provides near-real-time updates with the performance characteristics of static pages.
The webhook-driven approach is more efficient than time-based revalidation because it regenerates pages only when content actually changes, not on a fixed schedule. However, it requires reliable webhook delivery and careful handling of dependent pages — updating an author profile should regenerate all articles by that author, not just the author page.
CDN Distribution and Edge Caching
Static sites achieve their lowest latency when deployed to CDN edge nodes close to users. The pre-rendered HTML, CSS, JavaScript, and image files are distributed to edge locations worldwide, and each request is served from the nearest edge node. This geographic distribution eliminates the long-distance network round trips that dominate response time for centralized servers.
Cache Configuration for Static Assets
Static assets require different cache configurations based on their content characteristics:
- Content-hashed assets (main.a3f9.js, style.b2c1.css): Cache indefinitely with
Cache-Control: public, max-age=31536000, immutable. The content hash in the filename guarantees that changed content gets a new URL. - HTML pages: Short cache with revalidation:
Cache-Control: public, max-age=0, must-revalidatewith strong ETags. This ensures users always get the current version while allowing conditional requests that return 304 for unchanged content. - Images and media: Long cache with content-based URLs when possible. For images served through an image optimization pipeline, the URL includes transformation parameters that change when the source changes.
Edge Functions and Personalization
Pure static sites serve identical content to every visitor. When personalization is needed — geographically targeted content, A/B test variants, authenticated user experiences — edge functions add lightweight computation at the CDN edge without routing requests to an origin server.
Edge functions operate within strict resource constraints (typically 50 milliseconds CPU time and 128 MB memory) that prevent them from replacing full application servers. They excel at header manipulation, URL rewriting, cookie-based routing, and lightweight response transformation — exactly the operations needed for personalization of otherwise-static content.
Dynamic Content in Static Sites
Most "static" sites include dynamic elements: comments, user profiles, shopping carts, search results, real-time notifications. The Jamstack architecture handles these through client-side JavaScript calling APIs, rather than server-side rendering for each request.
Progressive Enhancement Pattern
The progressive enhancement pattern for static sites follows a clear hierarchy: render static content first (HTML from the build), enhance with personalized content second (client-side JavaScript calling APIs), and show interactive features third (event handlers, form submissions, real-time updates).
This hierarchy ensures that the fastest, most reliable content layer (static HTML) is always available, while dynamic features enhance the experience when JavaScript and network access are available. Users on slow connections see complete content quickly; interactive features load progressively as resources become available.
API-Driven Dynamic Sections
Common patterns for dynamic content in static sites:
- Comments and reviews: Load via API after the static page renders. Show a comment count in the static HTML (updated at build time) as a bridge between the static and dynamic experience.
- Search: Use client-side search indexes (pre-built during the static generation phase) for small sites. For larger sites, call a dedicated search API. The search interface renders statically; results load dynamically.
- User-specific content: Check authentication state client-side, then fetch personalized data from APIs. The static page includes placeholder UI for the personalized sections, replaced by actual content after the API response.
- Real-time data: WebSocket or Server-Sent Event connections established client-side after the static page loads. The static page shows the last known state from the build; the real-time connection updates it.
Jamstack Architecture Patterns
Jamstack (JavaScript, APIs, Markup) is the architectural pattern that codifies the static site approach. Pre-rendered markup served from a CDN, enhanced by client-side JavaScript, and powered by API services for dynamic functionality.
Monorepo vs Multi-Repo
Large Jamstack projects must decide whether to keep the static site, API services, and CMS configuration in a single repository or separate repositories. Monorepos simplify dependency management and atomic deployments but complicate build pipelines. Multi-repos provide cleaner separation of concerns but require coordination for cross-cutting changes.
Deployment and Preview
Static sites enable deployment previews — every pull request can trigger a full site build that deploys to a unique URL. Content editors and developers can review changes on a production-identical environment before merging. This capability is unique to static architectures because the build output is self-contained and can run anywhere.
Deploy previews also enable performance testing in CI. Run Lighthouse or Core Web Vitals measurements against the preview build to catch performance regressions before they reach production.
When Static Generation Fits — and When It Does Not
Static generation is ideal when content changes on editorial schedules, the number of unique pages is bounded, personalization requirements are limited, and performance is a primary concern. It is not ideal when content changes in real time, the page space is unbounded (user-generated content platforms), heavy personalization is required on every page, or build times become unacceptable.
| Use Case | Fit | Reason |
|---|---|---|
| Marketing sites | Excellent | Content changes on editorial schedule, performance critical for SEO |
| Documentation | Excellent | Content structured, changes via PRs, search can be client-side |
| Blogs and publications | Good (with ISR) | Content grows linearly, ISR handles publishing velocity |
| E-commerce catalog | Good (with ISR) | Product data changes via webhooks, pricing needs short revalidation |
| Social platforms | Poor | User-generated content is unbounded and real-time |
| Dashboards | Poor | Every view is personalized and data-driven |
Key Takeaways
Static site generation eliminates server-side computation at request time, producing the fastest possible page loads — single-digit TTFB from CDN edge nodes. ISR adds controlled freshness without sacrificing the performance model. Dynamic content loads progressively through client-side API calls, preserving the fast initial render while enhancing the experience for interactive use cases. The architecture fits best for content-driven sites where performance matters and content changes on editorial schedules rather than in real time.