Hugo Performance Optimization: Making Vitis Lightning Fast
The Need for Speed
In an age of bloated JavaScript frameworks, Vitis proves that fast, feature-rich sites don’t require sacrifice. Let’s explore the optimizations that deliver:
- โก <1s page load times
- ๐ฏ 95+ Lighthouse scores
- ๐ฆ <50KB initial payload
- ๐ Instant navigation with prefetch
Build-Time Optimizations
1. Intelligent Asset Bundling
Hugo’s asset pipeline handles:
{{ $css := resources.Get "css/style.css" }}
{{ $css = $css | postCSS | minify | fingerprint }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}">
This gives us:
- Minification - Removes whitespace and comments
- Fingerprinting - Cache-busting via content hashes
- PostCSS - Processes Tailwind and autoprefixes
2. Tailwind PurgeCSS
Vitis uses Tailwind’s JIT compiler:
// tailwind.config.js
module.exports = {
content: ["./layouts/**/*.{html,js}"],
// Only includes CSS for classes actually used
}
Result: 2.5MB Tailwind โ 15KB in production
3. Conditional Feature Loading
The knowledge graph only loads on relevant pages:
{{ if or .IsHome (eq .Type "graph") }}
<script src="{{ $d3js }}"></script>
<script src="{{ $graphjs }}"></script>
{{ end }}
Most pages ship zero JavaScript!
4. Optimized Syntax Highlighting
[markup.highlight]
noClasses = false # Use CSS instead of inline styles
style = "dracula"
One CSS file for all code blocks vs. inline styles on every <pre>.
Runtime Optimizations
1. Lazy Image Loading
<img
src="{{ $image.RelPermalink }}"
loading="lazy"
decoding="async"
alt="..."
>
Images below the fold load on scroll, not on page load.
2. Resource Hints
Critical resources prefetched:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://cdn.example.com">
3. Critical CSS Inlining
Above-the-fold styles inline in <head>:
<style>
/* Critical CSS for initial render */
body { font-family: Inter, sans-serif; }
.header { /* ... */ }
</style>
Eliminates render-blocking CSS for initial paint.
4. Font Optimization
@font-face {
font-family: 'Inter';
font-display: swap; /* Show fallback immediately */
src: url('/fonts/inter.woff2') format('woff2');
}
Font-display: swap prevents invisible text during load.
JavaScript Performance
1. Vanilla JS Over Frameworks
Vitis uses zero frameworks:
// React equivalent: ~50KB
// Vitis approach: ~5KB
document.getElementById('theme-toggle')
.addEventListener('click', toggleDarkMode);
For simple interactions, vanilla JS is 10x smaller.
2. Event Delegation
Instead of multiple listeners:
// โ One listener per item
items.forEach(item => {
item.addEventListener('click', handler);
});
// โ
One listener for all
container.addEventListener('click', e => {
if (e.target.matches('.item')) handler(e);
});
3. Debounced Search
let searchTimeout;
searchInput.addEventListener('input', e => {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
performSearch(e.target.value);
}, 300);
});
Reduces search operations from 50/second to ~3/second.
4. Intersection Observer
Efficient scroll detection:
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
loadContent(entry.target);
}
});
});
elements.forEach(el => observer.observe(el));
Network Optimizations
1. HTTP/2 Server Push
In Netlify config:
headers
for = "/*"
[headers.values]
Link = '''
</css/output.css>; rel=preload; as=style,
</js/main.js>; rel=preload; as=script
'''
2. Compression
Gzip/Brotli compression enabled:
# netlify.toml
[build.processing.css]
bundle = true
minify = true
[build.processing.js]
bundle = true
minify = true
Text assets compress ~70%.
3. CDN Distribution
Static assets served from edge locations:
User in Tokyo โ Tokyo CDN node (15ms)
vs.
User in Tokyo โ US origin server (250ms)
16x faster response times!
4. Cache Headers
Aggressive caching for static assets:
headers
for = "/css/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
Graph Visualization Performance
The knowledge graph visualizer handles large datasets:
1. Canvas Rendering Mode
For graphs with 500+ nodes:
if (nodeCount > 500) {
useCanvas(); // 10x faster than SVG
} else {
useSVG(); // Better for small graphs
}
2. Quadtree Optimization
D3’s force simulation uses spatial indexing:
simulation.force('collision',
d3.forceCollide()
.radius(20)
.iterations(2) // Reduce for performance
);
3. Filtering Instead of Re-rendering
// โ Recreate graph
function filterByTag(tag) {
destroyGraph();
const filtered = nodes.filter(n => n.tag === tag);
createGraph(filtered);
}
// โ
Hide/show nodes
function filterByTag(tag) {
nodes.forEach(n => {
n.style.opacity = n.tag === tag ? 1 : 0.1;
});
}
Measuring Performance
Tools Used
- Lighthouse - Overall scores
- WebPageTest - Real-world testing
- Chrome DevTools - Detailed profiling
- Bundle Analyzer - Asset size breakdown
Key Metrics
Vitis achieves:
First Contentful Paint: 0.8s
Largest Contentful Paint: 1.2s
Time to Interactive: 1.5s
Total Blocking Time: 50ms
Cumulative Layout Shift: 0.01
All in the “Good” range for Core Web Vitals!
Performance Budget
Strict limits enforced:
| Asset Type | Budget | Actual |
|---|---|---|
| HTML | 20KB | 12KB |
| CSS | 30KB | 15KB |
| JavaScript | 50KB | 8KB |
| Fonts | 100KB | 45KB |
| Images | 200KB | 120KB |
| Total | 400KB | 200KB |
We’re using only 50% of our budget!
Performance Anti-Patterns
Avoid These Mistakes
โ Loading all JS on every page
<!-- Don't do this -->
<script src="/js/graph.js"></script>
<script src="/js/search.js"></script>
<script src="/js/analytics.js"></script>
โ Conditional loading
{{ if .Params.hasGraph }}
<script src="/js/graph.js"></script>
{{ end }}
โ Unoptimized images

โ Hugo image processing
{{ $img := $img.Resize "800x webp q85" }}
โ Blocking resources in <head>
<script src="analytics.js"></script>
โ Async/defer attributes
<script src="analytics.js" defer></script>
Progressive Enhancement
Vitis works without JavaScript:
- Core content - Fully accessible with JS disabled
- Basic navigation - All links work
- Search - Degrades to site search
- Graph - Shows message: “Enable JS for interactive graph”
Enhanced features load progressively:
HTML only: โญ๏ธโญ๏ธโญ๏ธ (usable)
+ CSS: โญ๏ธโญ๏ธโญ๏ธโญ๏ธ (beautiful)
+ JS: โญ๏ธโญ๏ธโญ๏ธโญ๏ธโญ๏ธ (fully interactive)
Mobile Performance
Special optimizations for mobile:
1. Reduced Motion
@media (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition: none !important;
}
}
Respects user preferences and saves battery.
2. Smaller Breakpoint Images
{{ $mobile := $img.Resize "400x webp q80" }}
{{ $desktop := $img.Resize "1200x webp q85" }}
<picture>
<source media="(max-width: 640px)" srcset="{{ $mobile }}">
<img src="{{ $desktop }}" alt="...">
</picture>
Mobile users download 1/3 the data.
3. Touch-Optimized Interactions
.interactive-element {
min-width: 44px; /* WCAG touch target size */
min-height: 44px;
touch-action: manipulation; /* Removes 300ms delay */
}
The Results
Comparing Vitis to popular alternatives:
| Theme | Load Time | JS Size | Lighthouse |
|---|---|---|---|
| Vitis | 0.8s | 8KB | 98 |
| Theme A | 2.3s | 120KB | 72 |
| Theme B | 1.8s | 85KB | 81 |
| Theme C | 3.1s | 200KB | 65 |
Vitis is 2-4x faster than alternatives!
Implementation Checklist
Apply these optimizations to your site:
- Enable Hugo minification
- Configure Tailwind purge
- Add lazy loading to images
- Inline critical CSS
- Use font-display: swap
- Implement resource hints
- Enable Gzip/Brotli
- Set cache headers
- Remove unused JavaScript
- Optimize syntax highlighting
- Test with Lighthouse
- Monitor Core Web Vitals
Continuous Monitoring
Performance is ongoing:
# Run before every deploy
npm run test:performance
# Checks:
# - Bundle sizes within budget
# - Lighthouse score > 95
# - No new blocking resources
# - Image optimization
Future Optimizations
Exploring:
- ๐ Service Worker - Offline support
- ๐ Partial Hydration - Interactive islands
- ๐ WebP with AVIF fallback - Next-gen formats
- ๐ HTTP/3 - QUIC protocol benefits
Conclusion
Fast sites provide:
- โ Better UX - Users stay longer
- โ Higher rankings - Google rewards speed
- โ More conversions - Speed = revenue
- โ Lower costs - Less bandwidth
Vitis proves you can have it all: rich features, beautiful design, and blazing speed.
Learn More
- Building Your Digital Garden with Vitis
- Hugo Best Practices
- Web Performance Fundamentals
- Core Web Vitals Explained
Speed is a feature. Make it a priority from day one.