Best way to improve Core Web Vitals for a static HTML website

Hi everyone,

I’m working on a static HTML website and I’m trying to improve its Core Web Vitals, especially Largest Contentful Paint (LCP) and Cumulative Layout Shift (CLS).

I’ve already optimized images, minified CSS, and enabled compression, but I’m still looking for additional recommendations.

Which optimizations have made the biggest difference for your projects?

1 Like

What does CWV suggest you do? The thing doesnt just give you numbers.

One of the things you should do to improve the CLS is to add dimensions to the images (the width and height attributes of the img tag), or use the CSS aspect-ratio property.

1 Like

A static HTML site already has an advantage because there isn’t much server-side processing, so the biggest improvements usually come from optimizing what the browser downloads and renders.

I’d start by checking which Core Web Vitals metric is failing, since the fixes are different for each one:

  • LCP: Compress the hero image, use modern formats like WebP or AVIF, preload the main image or critical fonts, and avoid render-blocking CSS where possible.
  • CLS: Always specify image and iframe dimensions, and avoid inserting content above existing elements after the page has started rendering.
  • INP: Keep JavaScript minimal, defer non-essential scripts, and avoid long-running tasks on the main thread.

If you can share a PageSpeed Insights or Lighthouse report (or the site URL), it will be much easier to identify which optimization will have the biggest impact instead of guessing.

That’s helpful, thanks. One thing I’ve noticed is that it’s easy to focus on the obvious optimizations and then forget about the small things that add up. My images are already optimized, so I’m going to spend more time checking render-blocking resources and whether the browser is loading anything earlier than it actually needs.

I also like the idea of measuring after each change instead of applying everything at once. It should make it much easier to see which optimization is actually improving LCP or reducing CLS on my site. I’ll share the results once I’ve tested a few of these.

The optimization that made the single biggest LCP difference on my projects was content-visibility: auto on below-fold sections. It tells the browser to skip rendering entire DOM subtrees that aren’t visible yet — not just lazy-loading images, but skipping layout calculation, paint, and compositing for everything below the fold.

For a static HTML site, add this to any section that isn’t visible on initial load:

.below-fold-section {
content-visibility: auto;
contain-intrinsic-size: auto 500px;
}

The contain-intrinsic-size gives the browser an estimated height so the scrollbar doesn’t jump when the section eventually renders. I’ve seen this cut LCP by 30-50% on content-heavy pages because the browser focuses all its rendering budget on the above-fold content first.

For CLS specifically — beyond image dimensions (already mentioned above), the one thing people miss is third-party scripts. Ad scripts, analytics, and chat widgets that inject DOM elements after load are the #1 cause of CLS on otherwise well-optimized static sites. The fix is either to reserve space for them with min-height on their container, or defer them until after the page is interactive.

One more: if your LCP element is a hero image, add fetchpriority=“high” to the img tag. It tells the browser to download that image before other resources — noticeable improvement on slower connections.

I would also check areas like reducing unused JavaScript first then, optimizing font loading, and making sure critical resources load first. For CLS, defining image dimensions and avoiding late-loading elements can help a lot.

Using tools like Lighthouse or PageSpeed Insights can also show specific issues affecting your pages. Small improvements in loading order and resource handling often make a noticeable difference.

Your current checklist is on the right track. For LCP, I’d prioritize the hero image: serve a correctly sized AVIF/WebP, set width/height (or an aspect-ratio) to prevent CLS, and lazy-load everything below the fold. I also like testing the compressed output locally before uploading so unnecessary metadata is not carried along. Then rerun Lighthouse on a throttled mobile profile; the waterfall usually makes the next bottleneck obvious.

For a static HTML website, I’d start with the basics before making major changes. Static sites already have an advantage, so the biggest gains usually come from reducing what the browser has to download and render.

A few things that made the most difference for me:

  • Optimize and properly size images, preferably using WebP/AVIF.

  • Set explicit width and height (or aspect-ratio) on images to reduce CLS.

  • Preload only critical assets, especially the main above-the-fold image and important fonts.

  • Minify CSS/JS and remove unused CSS or JavaScript.

  • Defer non-critical JavaScript.

  • Use font-display: swap for web fonts and avoid loading unnecessary font weights.

  • Enable Brotli/Gzip compression and browser caching.

  • Use a CDN if the audience is geographically distributed.

  • Avoid third-party scripts unless they provide real value.

For LCP, I’d focus heavily on the hero/above-the-fold content. For CLS, look for images, ads, fonts, or dynamically injected elements that change the layout. For INP, reduce JavaScript and unnecessary event handlers.

I’d also run Lighthouse/PageSpeed Insights before and after each major change. That makes it much easier to identify what is actually helping instead of optimizing blindly.

With a well-built static HTML site, you can often get very good Core Web Vitals without doing anything complicated—the key is keeping the critical rendering path lean.