Platform-specific guides for diagnosing and fixing Core Web Vitals and performance issues on Ghost.
Core Web Vitals
Largest Contentful Paint (LCP)
Fix slow main content loading on Ghost. Target: under 2.5 seconds.
Cumulative Layout Shift (CLS)
Resolve visual stability issues causing layout shifts. Target: under 0.1.
Common Ghost Performance Issues
Theme Optimization
Ghost themes built with Handlebars can impact performance if not properly optimized.
Common issues:
- Heavy theme assets loading on every page
- Unoptimized theme JavaScript and CSS
- Excessive Handlebars helpers causing render delays
- Multiple font files loading unnecessarily
- Uncompressed theme assets
Optimization strategies:
- Use lightweight, performance-optimized themes (e.g., Casper, Ghost's default theme)
- Minimize custom fonts (2-3 font files maximum)
- Implement critical CSS for above-the-fold content
- Defer non-critical JavaScript loading
- Remove unused theme partials and helpers
- Compress and minify theme assets before packaging
- Use
{{asset}}helper to leverage Ghost's built-in asset optimization
Theme asset optimization:
{{!-- Use Ghost's asset helper for automatic minification and versioning --}}
<link rel="stylesheet" href="{{asset "css/screen.css"}}">
<script defer src="{{asset "js/app.js"}}"></script>
Image Optimization
Ghost has excellent built-in image handling, but proper configuration is essential.
Best practices:
- Use Ghost's responsive images feature (automatic srcset generation)
- Enable image optimization in Ghost config
- Compress images before upload (recommended: 80-85% quality)
- Use WebP format with automatic fallbacks
- Implement lazy loading for below-fold images
- Set appropriate image widths (Ghost default: 2000px max)
- Use Ghost's
{{img_url}}helper for automatic resizing
Ghost config for image optimization:
{
"imageOptimization": {
"resize": true,
"srcsets": true,
"sizes": {
"xs": 300,
"s": 600,
"m": 1200,
"l": 2000,
"xl": 2000
}
}
}
Using responsive images in themes:
{{!-- Automatic responsive images with srcset --}}
{{img_url feature_image size="l"}}
{{!-- Full responsive image implementation --}}
<img
srcset="{{img_url feature_image size="s"}} 300w,
{{img_url feature_image size="m"}} 600w,
{{img_url feature_image size="l"}} 1000w"
sizes="(max-width: 1000px) 100vw, 1000px"
src="{{img_url feature_image size="m"}}"
alt="{{title}}">
Database Performance
Ghost uses SQLite by default (self-hosted) or MySQL (Ghost Pro), both requiring optimization.
SQLite optimization (self-hosted):
- Regularly vacuum the database to reclaim space
- Keep database file under 1GB for optimal performance
- Monitor database file fragmentation
- Use WAL (Write-Ahead Logging) mode for better concurrency
SQLite commands:
# Vacuum database
sqlite3 /var/lib/ghost/content/data/ghost.db "VACUUM;"
# Enable WAL mode
sqlite3 /var/lib/ghost/content/data/ghost.db "PRAGMA journal_mode=WAL;"
MySQL optimization (self-hosted):
- Configure appropriate buffer pool size
- Enable query caching
- Optimize indexes on posts and tags tables
- Monitor slow query log
MySQL configuration:
[mysqld]
innodb_buffer_pool_size = 1G
query_cache_size = 64M
query_cache_type = 1
Caching Strategies
Ghost built-in caching:
- Ghost automatically caches rendered pages
- Cache invalidation happens on content updates
- Configure cache control headers appropriately
Ghost caching configuration:
{
"caching": {
"frontend": {
"maxAge": 600
},
"301": {
"maxAge": 31536000
}
}
}
CDN caching:
- Use CloudFlare, Fastly, or another CDN for edge caching
- Cache static assets (images, CSS, JS) for long durations
- Set shorter cache times for HTML pages (5-10 minutes)
- Implement stale-while-revalidate for better UX
Nginx caching (for self-hosted):
# Cache configuration
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=ghost_cache:10m max_size=1g inactive=60m;
location / {
proxy_cache ghost_cache;
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
proxy_cache_bypass $http_cache_control;
add_header X-Cache-Status $upstream_cache_status;
}
Third-Party Scripts and Integrations
Ghost sites often slow down due to external scripts.
Common culprits:
- Analytics scripts (Google Analytics, Plausible)
- Comment systems (Disqus, Commento)
- Social media embeds
- Email capture widgets
- Live chat tools
Optimization techniques:
- Load scripts asynchronously using Ghost's
{{ghost_head}}injection - Use code injection features wisely (Site Header vs. Site Footer)
- Implement lazy loading for comment sections
- Use lightweight analytics alternatives (Plausible, Fathom)
- Defer non-critical scripts to footer
Code injection best practices:
<!-- Site Footer injection for analytics -->
<script async src="https://analytics.example.com/script.js"></script>
<!-- Lazy load comments on interaction -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const commentsSection = document.querySelector('#comments');
const observer = new IntersectionObserver(function(entries) {
if(entries[0].isIntersecting) {
// Load comments script
const script = document.createElement('script');
script.src = 'https://comments.example.com/embed.js';
document.body.appendChild(script);
observer.disconnect();
}
});
if(commentsSection) observer.observe(commentsSection);
});
</script>
Ghost-Specific Performance Features
Content API Optimization
Ghost's Content API powers the frontend and requires optimization for high-traffic sites.
Best practices:
- Use
includeparameter judiciously (only fetch needed relations) - Implement proper pagination with
limitparameter - Cache API responses client-side where appropriate
- Use filters to reduce query overhead
- Leverage Ghost's built-in caching
Optimized API queries:
// Good: Fetch only what's needed
ghost.posts.browse({
limit: 15,
fields: 'id,title,slug,feature_image,published_at',
filter: 'featured:true',
include: 'tags'
});
// Bad: Fetching everything
ghost.posts.browse({
limit: 'all',
include: 'tags,authors,count.posts'
});
Member Authentication Performance
Ghost's membership features can add overhead if not optimized.
Optimization strategies:
- Use server-side rendering for member content when possible
- Cache member-specific content appropriately
- Implement efficient member session handling
- Use Ghost's native authentication instead of third-party solutions
Static Site Generation
For ultimate performance, consider using Ghost as a headless CMS with static site generation.
Recommended frameworks:
- Gatsby - React-based static site generator
- 11ty (Eleventy) - Lightweight JavaScript static site generator
- Next.js - React with static generation capabilities
- Astro - Modern static site builder
Benefits:
- Pre-rendered HTML for instant page loads
- No server-side processing on page views
- Better security (no exposed admin)
- Simplified hosting (static files only)
Ghost Hosting and Infrastructure
Self-Hosted Ghost Optimization
Node.js optimization:
// config.production.json
{
"server": {
"host": "0.0.0.0",
"port": 2368
},
"database": {
"client": "mysql",
"connection": {
"host": "localhost",
"user": "ghost",
"password": "your_password",
"database": "ghost_production"
},
"pool": {
"min": 2,
"max": 20
}
},
"mail": {
"transport": "SMTP"
},
"logging": {
"level": "info",
"rotation": {
"enabled": true,
"period": "1w",
"count": 10
}
},
"process": "systemd",
"paths": {
"contentPath": "/var/lib/ghost/content"
}
}
Nginx configuration for Ghost:
upstream ghost {
server 127.0.0.1:2368;
keepalive 64;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
# Gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_min_length 1000;
# Cache static assets
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
proxy_pass http://ghost;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Ghost Pro Performance
Ghost Pro includes many optimizations by default:
- Global CDN for all assets
- Automatic image optimization and resizing
- MySQL database optimization
- Automatic scaling for traffic spikes
- SSL/TLS with HTTP/2
Ghost Pro specific tips:
- Use custom integration features wisely
- Monitor usage in Ghost Admin
- Leverage built-in analytics instead of third-party tools when possible
Content Delivery Network (CDN)
CDN setup for self-hosted Ghost:
- Configure CloudFlare, Cloudinary, or Fastly
- Set appropriate cache rules for assets vs. content
- Use subdomain for static assets (e.g., cdn.yourdomain.com)
- Implement proper cache purging on content updates
CloudFlare Page Rules for Ghost:
Rule 1: yourdomain.com/content/images/*
- Cache Level: Cache Everything
- Edge Cache TTL: 1 year
- Browser Cache TTL: 1 year
Rule 2: yourdomain.com/assets/*
- Cache Level: Cache Everything
- Edge Cache TTL: 1 month
- Browser Cache TTL: 1 month
Rule 3: yourdomain.com/*
- Cache Level: Cache Everything
- Edge Cache TTL: 2 hours
- Browser Cache TTL: 30 minutes
Performance Testing for Ghost
Diagnostic Tools
- Google PageSpeed Insights - Core Web Vitals analysis
- Chrome DevTools Performance Tab - Detailed waterfall analysis
- Lighthouse - Comprehensive performance audit
- Ghost-CLI - Built-in diagnostics and monitoring
- WebPageTest - Advanced performance testing
Ghost-CLI diagnostics:
# Check Ghost status
ghost status
# View logs
ghost log
# Check for updates
ghost update --check
# Doctor command for health check
ghost doctor
Key Metrics for Ghost
Performance targets:
- Time to First Byte (TTFB): Under 200ms
- First Contentful Paint (FCP): Under 1.5s
- Largest Contentful Paint (LCP): Under 2.5s
- Time to Interactive (TTI): Under 3.5s
- Total page size: Under 2MB
- Total requests: Under 50
Platform-Specific Troubleshooting
Slow Homepage
Causes:
- Loading too many posts on homepage
- Unoptimized featured images
- Heavy theme with many assets
- Multiple third-party scripts
Fixes:
- Reduce number of posts shown (6-10 recommended)
- Optimize homepage layout and featured images
- Implement pagination or "Load More" functionality
- Lazy load images below the fold
- Use Ghost's routes.yaml for custom homepage structure
Slow Post Pages
Causes:
- Large, unoptimized feature images
- Heavy content with many images
- Related posts queries
- Comment system overhead
Fixes:
- Compress and resize feature images before upload
- Use Ghost's responsive images
- Optimize related posts logic in theme
- Lazy load comment systems
- Implement reading time estimates efficiently
Admin Dashboard Performance
Optimization tips:
- Limit posts per page in admin (25-50)
- Archive old drafts and posts
- Optimize database regularly
- Use latest Ghost version for admin improvements
- Clear browser cache if admin feels slow
Advanced Performance Techniques
Implement Service Workers
Use service workers for offline functionality and caching:
// sw.js - Basic service worker for Ghost
self.addEventListener('install', event => {
event.waitUntil(
caches.open('ghost-v1').then(cache => {
return cache.addAll([
'/',
'/assets/css/screen.css',
'/assets/js/app.js'
]);
})
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});
Implement AMP (Accelerated Mobile Pages)
Ghost has built-in AMP support:
- Enable AMP in Labs settings
- Customize AMP template in theme
- Test AMP pages with Google's AMP validator
- Monitor AMP performance in Search Console
Access AMP version:
https://yourdomain.com/post-slug/amp/
Optimize for Lighthouse Score
Strategies to improve Lighthouse score:
- Minimize render-blocking resources
- Eliminate unused CSS and JavaScript
- Properly size images
- Serve images in next-gen formats (WebP)
- Enable text compression
- Avoid enormous network payloads
- Use efficient cache policies
- Minimize critical request chains
Monitor Real User Metrics
Implement Real User Monitoring (RUM):
- Use Google Analytics with Web Vitals
- Implement custom performance tracking
- Monitor Core Web Vitals in Search Console
- Use third-party RUM tools (SpeedCurve, Calibre)
Ongoing Maintenance
Regular Performance Audits
Monthly tasks:
- Run Lighthouse audit on key pages
- Check Core Web Vitals in Search Console
- Review Ghost admin for database size
- Test site speed on real devices
- Monitor third-party script performance
- Check CDN cache hit ratios
Ghost Updates
- Keep Ghost updated to latest version
- Review Ghost changelog for performance improvements
- Test updates in staging environment first
- Backup before major version upgrades
- Monitor Ghost blog for optimization tips
Update Ghost:
# Check for updates
ghost update --check
# Update to latest version
ghost update
# Update to specific version
ghost update v5.x.x
Theme Maintenance
- Audit theme performance quarterly
- Remove unused theme features
- Update theme dependencies
- Test theme with latest Ghost version
- Consider switching to newer, faster themes
General Fixes
For universal performance concepts, see the Global Performance Issues Hub.