Your Static Site Isn't as Fast as You Think — Here's Where the Speed Is Actually Going
Photo: web developer analyzing website performance metrics on laptop with speed optimization charts, via img.freepik.com
There is a particular frustration that sets in when you have done everything right — chosen a static generator, deployed to a CDN, eliminated your origin server from the critical path — and your site still scores poorly on a Lighthouse audit. Users on mobile connections in Phoenix or rural Georgia are still waiting. The green checkboxes in your deployment dashboard feel increasingly hollow.
This is not an uncommon situation. The static site ecosystem has matured rapidly, and with that maturity has come a layer of tooling, component libraries, and convenience abstractions that quietly erode the performance advantages that made static hosting compelling in the first place. The problem is rarely your infrastructure. It is almost always what you are asking that infrastructure to deliver.
The Myth of Automatic Speed
Static hosting does not make a site fast. It removes a specific category of latency — server-side rendering time, database queries, origin round trips — and hands the remaining performance work back to the developer. Many teams treat the removal of that one bottleneck as the finish line. It is, at best, the starting line.
A static HTML file served from an edge node in Chicago can still take four seconds to become interactive if it is loading 800 kilobytes of JavaScript, three web fonts, a dozen uncompressed images, and a tag manager that fires six additional network requests before the page settles. The CDN delivered the initial bytes in 20 milliseconds. Everything after that was self-inflicted.
Audit First, Optimize Second
Before reaching for any fix, run a baseline audit. WebPageTest with a simulated mid-tier Android device on a 4G connection gives you a realistic picture of what a significant portion of your US audience actually experiences. Lighthouse in Chrome DevTools is useful for directional guidance but tends to flatter sites tested on desktop hardware. The goal is to identify your largest contributors to Total Blocking Time, Largest Contentful Paint, and Cumulative Layout Shift — not to chase a score.
Once you have a baseline, the optimization work becomes prioritizable rather than speculative.
JavaScript: The Most Expensive Asset You Are Probably Over-Serving
JavaScript is the single most impactful variable in static site performance, and it is the one most frequently overlooked because the files are technically static. A React component library bundled into a content site that has no interactive requirements is not a performance feature — it is a performance liability that you are paying for on every page load.
The first question worth asking is whether your site actually needs client-side JavaScript at all. Navigation, content display, contact forms handled by a third-party service, and even basic animations can all be accomplished with HTML and CSS. If the answer is that you do need JavaScript, the second question is whether it needs to load on every page or only on the pages where it is actually used.
Frameworks like Astro address this through component-level hydration. If you are not using a framework with that capability, manual code splitting and route-based chunking in your bundler configuration can achieve a similar outcome. The target for a content-focused static site should be under 50 kilobytes of JavaScript per page, excluding third-party scripts.
Image Delivery Is Doing More Damage Than You Realize
Images are consistently the largest contributors to page weight on content sites, and the gap between what developers serve and what they should serve remains wide. The modern baseline for image delivery in 2024 involves three things that are still not universally applied: serving WebP or AVIF formats instead of JPEG or PNG, sizing images to match their display dimensions rather than uploading originals, and using native lazy loading for below-the-fold assets.
If your static site pipeline does not include image optimization as a build step, it should. Hugo has built-in image processing. Eleventy has a well-maintained image plugin. Astro handles it natively. For teams on other stacks, a CDN that performs on-the-fly image transformation can serve as a reasonable fallback — though processing images at build time remains the more cost-efficient approach at scale.
A single hero image served at 2400 pixels wide to a mobile device displaying it at 400 pixels is transferring roughly 35 times more data than necessary. Multiply that across a site with dozens of pages and thousands of daily visitors, and the bandwidth cost and user experience impact become significant.
Caching Headers: The Free Performance Most Teams Leave on the Table
CDN caching is one of the clearest advantages of static hosting, but it only works if your deployment pipeline is setting cache headers correctly. A surprisingly large number of static sites reach production with default headers that either cache nothing or expire content far too aggressively.
The recommended baseline for static assets — JavaScript bundles, CSS files, fonts, and images with content-hashed filenames — is a Cache-Control value of max-age=31536000, immutable. Because the filename changes when the content changes, there is no risk of users receiving stale assets. For HTML files, which need to reflect updates without requiring a cache purge, Cache-Control: no-cache paired with a short s-maxage on your CDN layer gives you freshness control without sacrificing edge caching entirely.
Review your actual response headers using your browser's network tab or a tool like curl. If you see Cache-Control: no-store on static assets, or no cache headers at all, you are sending every visitor back to the origin on every request — defeating the core architecture of static hosting.
Third-Party Scripts: The Performance Budget You Did Not Approve
Analytics platforms, chat widgets, advertising tags, and A/B testing tools are the hidden cost centers of static site performance. Each one adds network requests, execution time, and in many cases layout shifts that your own code does not cause and cannot directly control.
The fix is not necessarily to remove them — though that is worth evaluating — but to load them in a way that does not block rendering. Defer all non-critical third-party scripts. Use the loading attribute strategically. Consider a privacy-friendly, self-hosted analytics alternative like Plausible or Umami that loads a single lightweight script rather than a multi-kilobyte SDK with its own dependency chain.
A Prioritized Starting Point
If you are looking for a sequence to work through, the following order reflects the typical impact-to-effort ratio for most static sites:
- Audit your JavaScript payload. Remove what is not needed. Split what remains.
- Compress and resize your images at build time. Move to WebP or AVIF.
- Verify your caching headers. Set long TTLs on hashed assets, controlled freshness on HTML.
- Defer or remove non-essential third-party scripts. Measure the before and after.
- Enable Brotli compression on your CDN or hosting provider if it is not already active.
- Preload critical fonts and use
font-display: swapto prevent invisible text during load.
None of these steps require a new framework, a new hosting provider, or a rewrite. They require an honest audit of what your static site is actually delivering and a willingness to close the gap between what the architecture promises and what the browser receives.
Speed is not a property of static hosting. It is a property of disciplined delivery. The infrastructure is ready when you are.