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.
Table of Contents
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
- Lighthouse: Built into Chrome DevTools
- WebPageTest: Detailed performance analysis
- GTmetrix: Comprehensive performance reports
- 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:
- Images: Responsive, modern formats, lazy loading
- CSS: Critical inlining, purging unused styles
- Caching: Aggressive static asset caching
- Delivery: Preloading critical resources
- 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!
