Skip to main content

5 Hugo Performance Tips for Lightning-Fast Static Sites

Practical techniques to optimize your Hugo static site for maximum performance, from image processing to build optimization.

3 min read
610 words

Static sites built with Hugo are inherently fast, but there’s always room for optimization. Here are five practical techniques I’ve used to achieve sub-200ms load times and perfect Lighthouse scores.

1. Optimize Image Processing

Hugo’s built-in image processing is incredibly powerful. Instead of serving full-resolution images, create responsive variants:

 1{{ $image := resources.Get "images/hero.jpg" }}
 2{{ $small := $image.Fit "640x" }}
 3{{ $medium := $image.Fit "1024x" }}
 4{{ $large := $image.Fit "1600x" }}
 5
 6<picture>
 7  <source media="(min-width: 1200px)" srcset="{{ $large.RelPermalink }}">
 8  <source media="(min-width: 768px)" srcset="{{ $medium.RelPermalink }}">
 9  <img src="{{ $small.RelPermalink }}" alt="Hero image" loading="lazy">
10</picture>

Modern Image Formats

Convert images to WebP or AVIF for better compression:

1{{ $webp := $image.Fit "800x webp" }}
2{{ $fallback := $image.Fit "800x jpg" }}
3
4<picture>
5  <source srcset="{{ $webp.RelPermalink }}" type="image/webp">
6  <img src="{{ $fallback.RelPermalink }}" alt="Optimized image">
7</picture>

2. Implement Critical CSS

Inline critical CSS to prevent render-blocking:

 1<!-- In your baseof.html -->
 2<style>
 3  /* Critical above-the-fold styles */
 4  body { font-family: system-ui, sans-serif; }
 5  .header { background: #fff; }
 6  /* ... other critical styles */
 7</style>
 8
 9<!-- Load full CSS asynchronously -->
10<link rel="preload" href="{{ $css.RelPermalink }}" as="style" onload="this.onload=null;this.rel='stylesheet'">

CSS Purging with Tailwind

If using Tailwind CSS, ensure proper purging:

1// tailwind.config.js
2module.exports = {
3  content: [
4    "./layouts/**/*.{html,js}",
5    "./content/**/*.{md,html}",
6    "./themes/**/layouts/**/*.{html,js}"
7  ],
8  // ... rest of config
9}

3. Optimize Build Performance

Enable Minification

Configure Hugo’s built-in minification:

1# hugo.toml
2[minify]
3  minifyOutput = true
4  [minify.tdewolff.html]
5    keepWhitespace = false
6  [minify.tdewolff.css]
7    precision = 0
8  [minify.tdewolff.js]
9    precision = 0

Use Hugo Modules for Themes

Instead of Git submodules, use Hugo modules for better caching:

1# hugo.toml
2[module]
3  [[module.imports]]
4    path = "github.com/username/theme-name"

4. Implement Smart Caching

Static Asset Caching

Configure long-term caching for static assets:

 1# netlify.toml
 2[[headers]]
 3  for = "/assets/*"
 4  [headers.values]
 5    Cache-Control = "public, max-age=31536000, immutable"
 6
 7[[headers]]
 8  for = "/*.html"
 9  [headers.values]
10    Cache-Control = "public, max-age=3600"

Resource Fingerprinting

Add cache-busting to processed assets:

1{{ $css := resources.Get "css/main.css" | postCSS | minify | fingerprint }}
2<link rel="stylesheet" href="{{ $css.RelPermalink }}" integrity="{{ $css.Data.Integrity }}">

5. Optimize Content Delivery

Preload Critical Resources

Preload important resources:

1<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
2<link rel="preload" href="{{ $criticalCSS.RelPermalink }}" as="style">

Lazy Load Non-Critical Content

Implement lazy loading for images and videos:

1<img src="{{ $image.RelPermalink }}" 
2     alt="Description" 
3     loading="lazy"
4     decoding="async">

Use Service Workers (Optional)

For advanced caching, implement a service worker:

 1// sw.js
 2const CACHE_NAME = 'site-v1';
 3const urlsToCache = [
 4  '/',
 5  '/css/main.css',
 6  '/js/main.js'
 7];
 8
 9self.addEventListener('install', event => {
10  event.waitUntil(
11    caches.open(CACHE_NAME)
12      .then(cache => cache.addAll(urlsToCache))
13  );
14});

Measuring Performance

Core Web Vitals

Monitor these key metrics:

  • LCP (Largest Contentful Paint): < 2.5s
  • FID (First Input Delay): < 100ms
  • CLS (Cumulative Layout Shift): < 0.1

Tools for Testing

  1. Lighthouse: Built into Chrome DevTools
  2. WebPageTest: Detailed performance analysis
  3. GTmetrix: Comprehensive performance reports
  4. PageSpeed Insights: Google’s performance tool

Real-World Results

After implementing these optimizations on this site:

  • Load Time: 150ms average (down from 2.3s)
  • Lighthouse Performance: 98/100
  • First Contentful Paint: 0.8s
  • Time to Interactive: 1.2s

Conclusion

Hugo’s performance is excellent out of the box, but these optimizations can take your site to the next level. Focus on:

  1. Images: Responsive, modern formats, lazy loading
  2. CSS: Critical inlining, purging unused styles
  3. Caching: Aggressive static asset caching
  4. Delivery: Preloading critical resources
  5. Monitoring: Regular performance audits

The key is to measure, optimize, and measure again. Every site is different, so profile your specific use case and optimize accordingly.

What performance techniques have worked best for your Hugo sites? Let me know - I’d love to hear about your experiences!

Share this post

Irhad Babic

Irhad Babic

Personal blog of Irhad Babic — engineering, AI, products, photos, notes.