Every few years the pendulum swings between “ship everything as JavaScript” and “ship as little JavaScript as possible”. For content sites — blogs, portfolios, docs — the second camp has clearly won, and Astro is the sharpest tool in it.
The islands model, briefly
Astro renders your entire page to static HTML at build time. Components that need interactivity opt in explicitly:
---import Chart from '../components/Chart.tsx';---
<!-- Rendered to HTML, zero JS shipped --><h1>Traffic report</h1>
<!-- Hydrated only when it scrolls into view --><Chart client:visible />Everything else — headers, footers, article bodies, cards — ships as plain HTML and CSS. The result is that your baseline JavaScript cost is close to zero, and every kilobyte you do ship is a deliberate decision.
Techniques that actually move the needle
Prefetch on hover and viewport
Astro’s built-in prefetch turns full page loads into near-instant navigations:
export default defineConfig({ site: 'https://example.com', prefetch: { prefetchAll: true, defaultStrategy: 'viewport', },});By the time a visitor clicks a link, the next page’s HTML is usually already in the cache. You get SPA-feeling navigation without a router, a hydration step, or a client-side state bug budget.
Self-host your fonts
A @fontsource import costs one line and removes an entire third-party origin:
import '@fontsource-variable/inter';No connection setup to fonts.googleapis.com, no layout shift from late-loading fonts, no consent-mode headaches. Variable fonts mean one file covers every weight you use.
Optimize the images you forgot about
Hero images get attention; the avatar in your footer doesn’t. Audit with the network tab sorted by size — the offenders are rarely where you expect. Set explicit width and height everywhere so the browser can reserve space before the image arrives.
What I stopped worrying about
- Client-side routing. Prefetched MPA navigation is indistinguishable for content sites.
- Skeleton screens. If the page renders in under 100ms, a skeleton is just a flash of fake content.
- Complex state management. Static pages don’t have state. This is a feature.
The scoreboard
This theme — the one you’re reading — ships roughly 4KB of JavaScript on a typical page: the theme toggle, mobile navigation, and a lazily-loaded search index. Lighthouse gives it a 100 in performance, and more importantly, it feels instant on a mid-range phone over 4G.
Fast is a feature. Static-first is how you afford it.