Back to Blog
Guide7 min read2026-05-01

Static Site Performance: How to Make Your Site Load Instantly

A practical guide to maximizing static site performance — from image optimization and code splitting to CDN caching and Core Web Vitals.

Static Site Performance: How to Make Your Site Load Instantly

Static sites start with a significant performance advantage — pre-built HTML served from a CDN is inherently faster than dynamically rendered pages. But "faster by default" doesn't mean "as fast as possible." There are concrete optimizations that separate a good static site from an exceptional one. Here's how to close that gap.

Understand Your Baseline

Before optimizing, measure. The three metrics that matter most for real-world performance are Google's Core Web Vitals:

  • Largest Contentful Paint (LCP) — how long until the main content is visible. Target under 2.5 seconds.
  • Cumulative Layout Shift (CLS) — how much the page jumps around as it loads. Target under 0.1.
  • Interaction to Next Paint (INP) — how responsive the page is to user input. Target under 200ms.

Run your site through [PageSpeed Insights](https://pagespeed.web.dev) and [WebPageTest](https://webpagetest.org) before and after each optimization to confirm the impact.

Optimize Images (The Biggest Win)

Images are typically the largest assets on any page and the most impactful to optimize.

Use modern formats. WebP and AVIF offer 25–50% smaller file sizes than JPEG and PNG at equivalent quality. Most modern static site generators handle format conversion automatically:

  • Next.js: built-in component
  • Astro: component from @astrojs/image
  • Hugo: resources.Process with webp format

Size images correctly. Never serve a 2400px image to display at 400px. Use responsive images with srcset to serve different sizes to different viewports.

Lazy load below-the-fold images. Add loading="lazy" to any image that isn't in the initial viewport. This defers fetching until the user scrolls near it.

Set explicit width and height on all tags to prevent layout shift (CLS).

Minimize JavaScript

Excess JavaScript is the primary cause of slow interactive sites. The browser must download, parse, and execute JS before the page responds to input.

Audit your bundle. Use tools like webpack-bundle-analyzer or Rollup's visualizer to see exactly what's in your JS bundle and where the weight comes from.

Remove unused code. Tree-shaking eliminates unused exports, but only if you import specifically (import { Button } from 'ui-lib') rather than wholesale (import * from 'ui-lib').

Code-split aggressively. Load JavaScript only for the features the current page needs. Next.js does this automatically per-page; Astro ships no JS by default and hydrates islands on demand.

Defer non-critical scripts. Third-party scripts for analytics, chat widgets, and A/B testing often load synchronously. Add defer or async attributes, and consider loading them after the initial page interaction.

Leverage CDN Caching Correctly

Static sites are uniquely well-suited to aggressive CDN caching, but the cache headers must be correct.

Long-lived cache for hashed assets. CSS and JS files with content hashes in their names (e.g., app.a3f2c1.js) should have Cache-Control: public, max-age=31536000, immutable. The content hash guarantees the URL changes when content changes, so it's safe to cache forever.

Short or no cache for HTML. HTML files reference hashed assets, so they must be fresh. Use Cache-Control: public, max-age=0, must-revalidate for HTML, ensuring browsers always get the latest routing information.

Preconnect to third-party origins. Add for external resources like fonts, analytics, and API domains. This establishes the TCP and TLS connection early, reducing latency when those resources are needed.

Optimize Web Fonts

Web fonts are a common source of invisible-text flash and layout shift.

  • Use font-display: swap in your @font-face declarations so text is visible in a fallback font while the custom font loads.
  • Subset fonts to include only the characters your site uses (reduces file size by 60–80% for Latin-only sites).
  • Self-host fonts rather than loading from Google Fonts to avoid cross-origin round-trips.
  • Use preload for your primary font file: .

Eliminate Render-Blocking Resources

Anything in that blocks rendering delays LCP. Audit your HTML head:

  • Move non-critical CSS to load asynchronously or inline the critical CSS.
  • Remove or defer any synchronous