Performance Optimization Guide
Performance Optimization Guide
This document explains the performance optimizations implemented for your Jekyll site.
What Was Optimized
1. ✅ Deferred CSS Loading
Impact: Reduces render-blocking CSS, improves First Contentful Paint by ~2.9s
External CSS files now use the preload technique with a fallback to stylesheet:
<link rel="preload" as="style" href="..." onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="..."></noscript>
This allows the browser to download CSS asynchronously without blocking page rendering.
2. ✅ Font Display Optimization
Impact: Prevents invisible text during font loading, saves ~20ms
Google Fonts now include &display=swap parameter:
- Before:
https://fonts.googleapis.com/css?family=Lora:400,700 - After:
https://fonts.googleapis.com/css?family=Lora:400,700&display=swap
This makes text visible immediately using fallback fonts while custom fonts load.
3. ✅ Deferred JavaScript
Impact: Eliminates render-blocking JS, reduces Total Blocking Time
All JavaScript files now use the defer attribute:
<script src="..." defer></script>
Benefits:
- Scripts download in parallel with page parsing
- Scripts execute after DOM is ready
- Maintains execution order
- Doesn’t block page rendering
4. ✅ Resource Hints (Preconnect & DNS Prefetch)
Impact: Reduces connection time to external resources by ~200-300ms
Added to <head>:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="dns-prefetch" href="https://stackpath.bootstrapcdn.com">
This tells browsers to establish connections early, before resources are requested.
5. ✅ Responsive Image Component
Created _includes/responsive-image.html for optimized image loading.
Usage in your posts:
<picture>
<source srcset="/assets/img/photo.webp" type="image/webp">
<img src="/assets/img/photo.jpg"
alt="Photo description"
width="800"
height="600"
loading="lazy"
>
</picture>
Expected Performance Improvements
Based on PageSpeed recommendations, these changes should improve:
| Metric | Before | Expected After | Improvement |
|---|---|---|---|
| Performance Score | 62 | 80-85 | +18-23 points |
| First Contentful Paint | 5.0s | 2.5-3.0s | -2.0-2.5s |
| Largest Contentful Paint | 7.9s | 4.0-5.0s | -2.9-3.9s |
| Total Blocking Time | 90ms | 30-50ms | -40-60ms |
| Speed Index | 5.6s | 3.5-4.0s | -1.6-2.1s |
Next Steps for Further Optimization
A. Image Optimization (Manual)
See IMAGE_OPTIMIZATION.md for detailed guide.
Quick wins:
# Navigate to images directory
cd assets/img
# Optimize avatar
convert mylogo.jpg -resize 200x200\> -quality 85 mylogo-opt.jpg
convert mylogo.jpg -resize 200x200\> -quality 85 mylogo.webp
# Update _config.yml to use optimized avatar
avatar: "/assets/img/mylogo-opt.jpg"
B. Enable Caching on GitHub Pages
GitHub Pages automatically sets cache headers, but you can verify with:
curl -I https://heaohan.github.io/
Look for:
cache-control: max-age=600
For longer caching, consider:
- Using a CDN (Cloudflare, Netlify)
- Self-hosting with custom server configuration
C. Minify CSS/JS (Automated)
Add to _config.yml:
# Compress HTML
compress_html:
clippings: all
comments: all
endings: all
profile: false
# Sass compression
sass:
style: compressed
Install Jekyll minification:
gem install jekyll-minifier
Add to _config.yml:
plugins:
- jekyll-minifier
D. Remove Unused CSS
Tools to identify unused CSS:
- Chrome DevTools Coverage tab
- PurgeCSS (https://purgecss.com/)
Example PurgeCSS config:
// purgecss.config.js
module.exports = {
content: ['./_site/**/*.html'],
css: ['./_site/assets/css/**/*.css']
}
E. Optimize Third-Party Scripts
Current third-party resources:
- Bootstrap CSS (147KB)
- Font Awesome (76KB)
- jQuery (31KB)
- Bootstrap JS (27KB)
Consider:
- Self-hosting to control caching
- Tree-shaking to include only used components
- Replacing with lighter alternatives:
- jQuery → Vanilla JS
- Bootstrap → Tailwind CSS
- Font Awesome → SVG icons
F. Enable Service Worker for Offline Support
Create sw.js in root:
const CACHE_NAME = 'v1';
const urlsToCache = [
'/',
'/assets/css/beautifuljekyll.css',
'/assets/js/beautifuljekyll.js'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(urlsToCache))
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
Register in _includes/head.html:
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
</script>
Testing Performance
After deploying changes, test with:
- PageSpeed Insights
https://pagespeed.web.dev/analysis/https-heaohan-github-io/ - WebPageTest
https://www.webpagetest.org/ - Lighthouse (Chrome DevTools)
F12 → Lighthouse tab → Generate report - GTmetrix
https://gtmetrix.com/
Deployment
- Test locally:
bundle exec jekyll serve - Check http://localhost:4000 in Chrome DevTools:
- Network tab: Verify defer/preload attributes
- Lighthouse: Run performance audit
- Coverage tab: Check unused CSS/JS
- Commit and push:
git add . git commit -m "feat: implement performance optimizations" git push origin master -
Wait 2-5 minutes for GitHub Pages to build
- Test live site with PageSpeed Insights
Monitoring
Set up regular performance monitoring:
- GitHub Actions - Weekly performance tests
- Google Search Console - Core Web Vitals
- Uptime monitoring - UptimeRobot, StatusCake
Troubleshooting
Issue: Fonts not loading
Solution: Check browser console for CORS errors. Ensure preconnect includes crossorigin for font files.
Issue: JavaScript errors after adding defer
Solution: Some scripts may need to execute in order. Move critical scripts to <head> without defer, or use async instead.
Issue: CSS loads with visible flash
Solution: Inline critical CSS in <head>:
<style>
/* Critical above-the-fold CSS */
body { font-family: sans-serif; }
.navbar { background: #fff; }
</style>
Issue: Images appear unstyled
Solution: Ensure width/height attributes match aspect ratio:
<!-- 800x600 image (4:3 ratio) -->
<img src="photo.jpg" width="800" height="600">
Results Tracking
Document your improvements:
| Date | Performance | FCP | LCP | TBT | CLS | Notes |
|---|---|---|---|---|---|---|
| Dec 7, 2025 | 62 | 5.0s | 7.9s | 90ms | 0 | Baseline |
| After deploy | ? | ? | ? | ? | ? | With optimizations |