- ✅ Homepage/shared images converted to WebP (3.2MB → 700KB)
- ✅
<picture>tags with PNG fallbacks on all 37 pages - ✅ Removed 3 unused Google Fonts (VT323, Silkscreen, Playfair Display)
- ✅ Switched
display=block→display=swap(text visible immediately) - ✅ Lazy-loaded Luma embed iframe
The problem: 75 images across tutorial pages, totaling ~64MB. Zero have loading="lazy". The Jade Wallet tutorial alone loads 21MB of PNGs upfront — on bad WiFi that's minutes of waiting.
Worst offenders:
bitaxe-supra-motherboard.png— 25MB (single image!)vibecode.png— 3.6MBcyberian-mine-logo.png— 2.3MB- 15+ Jade Wallet screenshots at 600KB-1.9MB each
Fix (two parts):
- Zero-effort, huge impact. Browser only loads images as you scroll to them.
- Keeps first page load to just HTML + CSS + above-fold content.
- Skip lazy on the first 1-2 images per page (hero/intro images should load immediately).
- Same technique as homepage —
cwebpconversion +<picture>fallbacks. - Expected savings: 60-80% reduction. 64MB → ~15MB total.
- The 25MB bitaxe image alone will probably drop to 2-3MB.
- Can do this with a batch script in one pass.
Impact: Pages that currently take 30+ seconds on bad WiFi → 2-3 seconds for initial render.
The problem: Every page load makes 2-3 requests to fonts.googleapis.com then fonts.gstatic.com to download font files. On bad WiFi, this adds 1-3 seconds of render-blocking time even with display=swap — the DNS lookup + TLS handshake to Google's servers is the bottleneck.
Fix:
- Download the WOFF2 files for Press Start 2P and Space Grotesk (latin subset only — ~60KB total)
- Host them at
static/fonts/ - Replace Google Fonts
<link>tags with local@font-facedeclarations instyles.css - Remove all
fonts.googleapis.comandfonts.gstatic.comreferences - Add
font-display: swapto each@font-face
Impact: Eliminates 2-3 external DNS lookups + connections per page load. Fonts served from same CDN as the site.
The problem: GitHub Pages has a fixed 10-minute cache TTL and no custom cache headers. Every visit re-downloads everything. On bad WiFi, repeat visits are just as slow as first visits.
Fix:
- Move DNS from Namecheap (
registrar-servers.com) to Cloudflare (free tier) - Keep GitHub Pages as origin — Cloudflare sits in front as CDN/cache
- Cloudflare free tier gives you:
- Global edge caching — assets served from nearest PoP (NYC has several)
- Custom cache rules — set images/fonts to cache for 1 year, HTML for 1 hour
- Auto-minification — CSS/JS/HTML minified on the fly
- Brotli compression — better than gzip, ~15-20% smaller
- HTTP/2 + HTTP/3 — multiplexed connections, faster on bad WiFi
- Always Online — serves cached version if GitHub Pages is down
Impact: Repeat visitors load in <500ms. First-time visitors benefit from edge caching (content closer to them).
Effort: ~15 minutes to set up. Change two nameservers at Namecheap, configure cache rules in Cloudflare dashboard.
The problem: Once someone visits the site, if their connection drops or degrades, they get nothing. For a Freedom Tech site, offline resilience is on-brand.
Fix:
- Add a simple service worker (
sw.js) that caches:- All CSS and JS files (precache on first visit)
- The homepage and main page shells
- Visited pages and their images (cache-on-navigate)
- Stale-while-revalidate strategy: serve cached version instantly, update in background
- Offline fallback page for unvisited pages
Impact: Return visits load instantly regardless of connection. Pages you've visited before work offline. Very on-brand for Freedom Tech.
Effort: ~50 lines of JS. No build tools needed.
The problem: footer.js still loads nostr_logo.png and tor_logo.png (small — 18-22KB each, but easy fix). Also, some mobile-specific issues from the audit.
Fix:
- Update
footer.jsto use WebP with PNG fallback - Add 480px breakpoint to classes-events page
- Reduce Luma iframe height on mobile (550px → 400px)
- Verify Press Start 2P heading doesn't overflow on 320px screens
- Even smaller than WebP (30-50% smaller) but Safari only added support in 2023
- Could add as a third
<source>in<picture>tags: AVIF → WebP → PNG - Wait until browser support is >95%
- Services like Cloudflare Images or imgix can serve optimally-sized images per device
- Overkill for this site size, but worth considering if tutorial count grows significantly
- Extract above-the-fold CSS and inline it in
<head>, load the rest async - Eliminates the render-blocking CSS request
- More complex to maintain — only do this if Lighthouse still complains after the above fixes
- Tutorial images: lazy loading (30 min, massive impact)
- Tutorial images: WebP conversion (1 hour with batch script)
- Self-host fonts (30 min)
- Cloudflare CDN (15 min setup, Harrison needs to change nameservers)
- Service worker (1 hour)
- Footer + mobile fixes (20 min)
Total estimated time: ~3.5 hours for everything. Expected result: Site loads in 1-2 seconds on good WiFi, 3-5 seconds on bad WiFi (down from 10-30+ seconds currently).