Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/workflows/lighthouse-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
uses: actions/checkout@v4

- name: Install Flox
uses: flox/install-flox-action@v1
uses: flox/install-flox-action@v2

- name: Activate Flox environment
run: flox activate
Expand Down Expand Up @@ -54,10 +54,20 @@ jobs:
rm .server.pid
fi

- name: Save base branch Lighthouse report
run: |
# Move the base report to /tmp so it persists across checkouts
mv lighthouse-base.json /tmp/lighthouse-base.json

# Test PR branch
- name: Checkout PR branch
uses: actions/checkout@v4

- name: Restore base branch Lighthouse report
run: |
# Move the base report back to the working directory
mv /tmp/lighthouse-base.json lighthouse-base.json

- name: Start dev server for PR branch
run: |
flox activate -- livereload --port 8888 > /dev/null 2>&1 &
Expand Down
8 changes: 1 addition & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ result
/TODO.md

# Lighthouse reports
lighthouse-report.html
lighthouse-report.json
lighthouse-report-full.html
lighthouse-report-full.json
lighthouse-mobile.html
lighthouse-mobile.json
lighthouse-perf.json
/lighthouse-*

# Just recipes temp files
.server.pid
51 changes: 34 additions & 17 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## Project Overview

This is a single-page website for Planet Nix, built with simplicity in mind - no build steps required. Optimized for performance with a Lighthouse score of 84/100.
This is a single-page website for Planet Nix, built with simplicity in mind - no build steps required. Optimized for performance with a Lighthouse score of 91/100.

## Technology Stack

Expand Down Expand Up @@ -32,11 +32,10 @@ This is a single-page website for Planet Nix, built with simplicity in mind - no

```
planetnix-website/
├── index.html # Main single-page website file
├── index.html # Main single-page website (with inlined CSS)
├── assets/ # All website resources
│ ├── css/
│ │ ├── pico.min.css # Pico CSS framework
│ │ └── style.css # Custom styles
│ │ └── pico.min.css # Pico CSS framework
│ ├── fonts/ # Local fonts (Geist, Geist Mono)
│ ├── images/ # Optimized images (76.6% size reduction)
│ └── js/ # JavaScript files (if needed)
Expand All @@ -50,8 +49,8 @@ planetnix-website/
### Assets Folder

All extra resources needed for the website should be placed in the `assets/` folder:
- **assets/css/** - CSS stylesheets (Pico CSS + custom styles)
- **assets/fonts/** - Local font files (Geist, Geist Mono)
- **assets/css/** - CSS stylesheets (Pico CSS only; custom styles are inlined in index.html for performance)
- **assets/fonts/** - Local font files (Geist 400/700, Geist Mono 400 - only critical weights)
- **assets/images/** - Optimized images, icons, logos, and graphics
- All images optimized using pngquant and optipng
- Lazy loading for below-the-fold images
Expand All @@ -76,14 +75,15 @@ just dev
**Important**: All `just` commands must be run within the Flox environment using `flox activate --`:

```bash
flox activate -- just # List all available commands
flox activate -- just dev # Start development server
flox activate -- just perf # Quick performance check (84/100 current)
flox activate -- just lighthouse # Full performance audit with HTML report
flox activate -- just lighthouse-mobile # Mobile performance test
flox activate -- just optimize-images # Re-optimize images
flox activate -- just clean # Remove generated reports
flox activate -- just info # Show environment info
flox activate -- just # List all available commands
flox activate -- just dev # Start development server
flox activate -- just perf # Quick performance check (91/100 current)
flox activate -- just lighthouse # Full performance audit with HTML report
flox activate -- just lighthouse-mobile # Mobile performance test
flox activate -- just optimize-images # Re-optimize all PNG images
flox activate -- just generate-responsive-images # Create responsive image sizes (480w, 768w, 1024w)
flox activate -- just clean # Remove generated reports
flox activate -- just info # Show environment info
```

Alternatively, activate the Flox shell first, then run just commands directly:
Expand Down Expand Up @@ -121,17 +121,34 @@ just perf
- **Performance first**: Every optimization counts
- Images: 2.3 MB → 556 KB (76.6% reduction)
- Initial load: Only 139 KB of images (lazy loading)
- Lighthouse score: 84/100 and improving
- CSS inlined: Custom styles inlined to eliminate render-blocking requests
- Lighthouse score: 91/100
- **Reproducible environment**: Flox ensures consistent setup across machines
- **Automated quality**: CI/CD prevents performance regressions

## Performance Optimizations

### Implemented
- ✅ **Image optimization**: pngquant + optipng (76.6% size reduction)
- ✅ **Responsive images**: Multiple sizes (480w, 768w, 1024w, 1280w) for adaptive loading
- **Why responsive?** Saves 142 KB on mobile by serving appropriately sized images
- Background images use `srcset` to load optimal size based on viewport
- Generated using `just generate-responsive-images` command
- Smaller images for mobile (480w: ~15KB) vs desktop (1280w: ~100KB)
- ✅ **Lazy loading**: Below-the-fold images load on demand
- ✅ **Local fonts**: Geist and Geist Mono with font-display: swap
- ✅ **Minimal CSS**: Pico CSS is only 22 KB minified
- ✅ **Explicit image dimensions**: All images have width/height attributes
- **Why?** Prevents layout shift (CLS) during page load
- CSS ensures responsiveness: `max-width: 100%; height: auto;`
- Browser calculates aspect ratio from dimensions, CSS controls display size
- ✅ **CSS inlining**: Custom styles (11.4 KB) inlined in HTML to eliminate render-blocking request
- **Why inlined?** Eliminates 700ms render-blocking network request, improves FCP and LCP
- Pico CSS (22 KB) remains external as it's cached and essential for semantic styling
- ✅ **Font optimization**: Only critical font weights loaded (Geist 400/700, Geist Mono 400)
- Reduced from 18 font files to 3, eliminating 100+ KB of unused fonts
- Preloaded with `fetchpriority="high"` for faster discovery
- Using `font-display: swap` to prevent invisible text
- ✅ **LCP optimization**: Hero moon image with `fetchpriority="high"` and preload hint
- ✅ **Zero layout shift (CLS: 0)**: Inline CSS + explicit image dimensions prevent FOUC
- ✅ **Semantic HTML**: No unnecessary divs or classes

### Monitoring
Expand Down
41 changes: 39 additions & 2 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@
# - Stop server when done
#
# Image Optimization:
# just optimize-images - Optimize all PNG images in assets/images/
# Uses pngquant (65-80% quality) + optipng
# just optimize-images - Optimize all PNG images in assets/images/
# Uses pngquant (65-80% quality) + optipng
# just generate-responsive-images - Generate 480w, 768w, 1024w versions of
# background images for responsive loading
# Creates WebP versions optimized for mobile
#
# Utilities:
# just info - Show Flox environment information
Expand Down Expand Up @@ -167,6 +170,40 @@ optimize-images:
done
@echo "✅ Image optimization complete"

# Generate responsive image sizes for background images
# Creates 480w, 768w, and 1024w versions of specified images for responsive loading
# Original 1280w images are preserved
generate-responsive-images:
@echo "🖼️ Generating responsive image sizes..."
@cd assets/images && \
for img in location-bg about-bg; do \
echo " Processing $${img}..."; \
if [ -f "$${img}.png" ]; then \
echo " Creating 480w version..."; \
sips -z 320 480 "$${img}.png" --out "$${img}-480w.png" > /dev/null 2>&1; \
echo " Creating 768w version..."; \
sips -z 512 768 "$${img}.png" --out "$${img}-768w.png" > /dev/null 2>&1; \
echo " Creating 1024w version..."; \
sips -z 682 1024 "$${img}.png" --out "$${img}-1024w.png" > /dev/null 2>&1; \
else \
echo " ⚠️ $${img}.png not found, skipping"; \
fi; \
done && \
echo " Optimizing resized PNGs..." && \
just optimize-images > /dev/null && \
echo " Converting to WebP..." && \
for img in location-bg about-bg; do \
for size in 480 768 1024; do \
if [ -f "$${img}-$${size}w.png" ]; then \
flox activate -- cwebp -q 90 "$${img}-$${size}w.png" -o "$${img}-$${size}w.webp" 2>&1 | grep -E "(Saving|Output)" || true; \
fi; \
done; \
done
@echo "✅ Responsive images generated"
@echo ""
@echo "📊 File sizes created:"
@cd assets/images && ls -lh *-{480,768,1024}w.webp 2>/dev/null || echo "No responsive images found"

# Show current environment info
info:
@echo "📦 Environment Information:"
Expand Down
39 changes: 28 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

A beautifully simple, single-page website built with modern web standards and optimized for performance. No build steps, no complex tooling - just clean HTML, elegant CSS, and lightning-fast load times.

[![Performance](https://img.shields.io/badge/Lighthouse-84%2F100-brightgreen)]()
[![Performance](https://img.shields.io/badge/Lighthouse-91%2F100-brightgreen)]()
[![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg)]()

## ✨ What Makes This Special
Expand Down Expand Up @@ -66,7 +66,8 @@ just lighthouse-mobile # Test mobile performance
just perf # Quick performance score check

# Image Optimization
just optimize-images # Optimize all PNG images
just optimize-images # Optimize all PNG images
just generate-responsive-images # Create responsive sizes (480w, 768w, 1024w)

# Utilities
just clean # Remove generated reports
Expand All @@ -76,12 +77,11 @@ just clean # Remove generated reports

```
planetnix-website/
├── index.html # Main single-page website
├── index.html # Main single-page website (with inlined CSS)
├── assets/
│ ├── css/
│ │ ├── pico.min.css # Pico CSS framework
│ │ └── style.css # Custom styles
│ ├── fonts/ # Local fonts (Geist, Geist Mono)
│ │ └── pico.min.css # Pico CSS framework
│ ├── fonts/ # Local fonts (Geist 400/700, Geist Mono 400)
│ ├── images/ # Optimized images and icons
│ └── js/ # JavaScript (if needed)
├── Justfile # Command runner recipes
Expand All @@ -100,11 +100,28 @@ planetnix-website/

## 🏎️ Performance

We take performance seriously:

- **Images**: Optimized from 2.3 MB → 556 KB (76.6% reduction)
- **Initial Load**: Only 139 KB of images load initially (lazy loading)
- **Lighthouse Score**: 84/100 and improving
We take performance seriously. Here's what we've optimized:

### 📊 Lighthouse Score: **91/100**

### Optimizations Applied
- **Images**: Optimized from 2.3 MB → 556 KB (76.6% reduction using pngquant + optipng)
- **Responsive Images**: Multiple sizes (480w, 768w, 1024w, 1280w) for adaptive loading
- **Why?** Saves 142 KB on mobile by serving appropriately sized images
- Mobile devices load small versions (~15KB) instead of full-size (~100KB)
- Regenerate with: `just generate-responsive-images`
- **Initial Load**: Only 139 KB of images load initially (lazy loading for below-the-fold content)
- **Explicit Image Dimensions**: All images have width/height to prevent layout shift
- **Why?** CLS score of 0 (perfect!) - no content jumping during load
- Remains fully responsive with CSS: `max-width: 100%; height: auto;`
- **CSS Inlining**: Custom styles (11.4 KB) inlined in HTML
- **Why?** Eliminates 700ms render-blocking network request
- Pico CSS remains external for caching benefits
- **Font Optimization**: Only 3 critical font weights loaded (Geist 400/700, Geist Mono 400)
- Reduced from 18 font files to 3, eliminating 100+ KB of unused fonts
- Preloaded with `fetchpriority="high"` for instant discovery
- **LCP Optimization**: Hero image prioritized with `fetchpriority="high"` and preload
- **Zero Layout Shift (CLS: 0)**: Inline CSS + explicit image dimensions prevent FOUC
- **CI/CD**: Automated performance testing on every PR

## 🤝 Contributing
Expand Down
Loading