Building a site with a static generator usually gives you a head start on performance, but simply using a static site generator isn’t a magic bullet. In my experience, many developers fall into the trap of thinking that because they are using a Jamstack architecture, they don’t need to worry about performance. However, as soon as you add a few heavy images, some third-party scripts, and a complex CSS framework, your scores plummet.
Optimizing Core Web Vitals for Jamstack is about moving beyond the ‘static’ part and focusing on how the browser actually renders your content. Whether you are debating Astro vs Next.js for static sites or building a custom pipeline, the goal remains the same: LCP, INP (which replaced FID), and CLS must be in the green.
Prerequisites
- A deployed Jamstack site (Next.js, Astro, Hugo, or Gatsby).
- Access to Google PageSpeed Insights or Chrome DevTools.
- Basic familiarity with CSS and JavaScript optimization.
- An understanding of Jamstack architecture best practices.
Step 1: Crushing Largest Contentful Paint (LCP)
LCP measures when the largest visible element is rendered. In most Jamstack sites, this is either a hero image or a large heading. To optimize this, I focus on the critical rendering path.
Prioritize the Hero Image
Stop lazy-loading your hero image. If you lazy-load everything, the browser doesn’t start downloading the most important image until the JS kicks in, killing your LCP. Instead, use fetchpriority="high".
<!-- Bad: Lazy loading the hero image --
<img src="/hero.jpg" loading="lazy" alt="Hero">
<!-- Good: Prioritizing the hero image --
<img src="/hero.webp" fetchpriority="high" alt="Hero">
Optimize Image Formats
I always convert images to WebP or AVIF. If you’re using Next.js, the next/image component handles this automatically. If you’re using Astro, the astro:assets module is a game-changer for reducing payload sizes.
Step 2: Eliminating Cumulative Layout Shift (CLS)
CLS happens when elements move around while the page is loading. This is usually caused by images without dimensions or dynamically injected ads/widgets.
Set Explicit Dimensions
Always define width and height attributes. This tells the browser to reserve the space before the image actually downloads.
<!-- This prevents layout shift --
<img src="/blog-thumbnail.jpg" width="800" height="450" alt="Thumbnail">
Reserve Space for Dynamic Content
If you’re fetching data from a headless CMS and injecting a banner, wrap it in a div with a minimum height. As shown in the image below, failing to reserve space causes the entire page to “jump” once the API response arrives.
Step 3: Improving Interaction to Next Paint (INP)
While FID was the old standard, INP is now the metric to watch. It measures the latency of all interactions. In Jamstack sites, the biggest culprit is “Hydration Overload”—where the browser freezes while the JavaScript takes over the static HTML.
Implement Island Architecture
This is why I’ve moved toward Astro for content-heavy sites. Instead of hydrating the entire page, you only hydrate the interactive components. This drastically reduces the main thread work.
<!-- Astro example: Only the Header is interactive --
<Header client:visible />
<StaticContent /> <!-- No JS sent to client for this part --
<Footer client:load />
Defer Non-Critical JS
Third-party scripts (Analytics, Hotjar, Chatbots) are performance killers. Use defer or async, or better yet, use a tool like Partytown to move these scripts to a web worker.
Pro Tips for Jamstack Performance
- Edge Caching: Deploy your site to a global CDN like Vercel, Netlify, or Cloudflare Pages. This reduces the Time to First Byte (TTFB), which is the foundation of LCP.
- Font Optimization: Use
font-display: swap;in your CSS to prevent invisible text during font loading. - Critical CSS: Inline your critical CSS in the
<head>and load the rest asynchronously.
Troubleshooting Common Issues
“My Lighthouse score is high, but real-user data (CrUX) is low.”
This usually means your local machine is faster than your users’ devices. Test your site using “Throttling” in Chrome DevTools (set to Mid-tier Mobile) to see the real experience.
“Next.js hydration errors are slowing me down.”
Ensure your server-rendered HTML matches the client-rendered HTML exactly. Mismatches force the browser to re-render components, spiking your INP.
What’s Next?
Once you’ve nailed your vitals, start looking at your conversion rates. Performance isn’t just about a score; it’s about user retention. If you’re still wondering is Jamstack worth it in 2026, the answer is yes—provided you actually optimize it.