High-Performance Photography Portfolio (Case Study)
A personal photography portfolio built to deliver a visually rich, high-resolution image gallery that is exceptionally fast and accessible on all devices. Built with Eleventy, Node.js, and advanced image optimization techniques.

Technology Stack
Core Framework
Performance & Optimization
Project Overview
This project is a personal photography portfolio built from the ground up to solve a common problem: how to deliver a visually rich, high-resolution image gallery that is also exceptionally fast and accessible on all devices. The primary goal was to create a seamless user experience where the technology gets out of the way, allowing the photography to shine, while also building a highly automated and maintainable developer workflow.
My Role & Technologies
As the sole developer, I architected and executed the entire project, from UI/UX design to the final deployment strategy.
- Core Stack: Eleventy, Node.js, Tailwind CSS, DaisyUI
- Performance & Optimization: Sharp.js, Terser, eleventy-plugin-files-minifier, critical CSS package
- Offline Caching: Custom Service Worker
The Core Challenge: Performance vs. Quality
The central challenge was to avoid the typical trade-off between image quality and site performance. High-resolution photos are essential for a photography portfolio but are also the primary cause of slow load times and high data consumption, especially on mobile networks. My solution had to be automated, scalable, and deeply integrated into the build process.
Key Solutions & Technical Implementation
I engineered a four-part solution focused on automation and a performance-first mindset.
a. Automated Image Processing Pipeline
I wrote a custom Node.js script using Sharp.js that runs automatically during the build process. For every source image, it:
- Generates Responsive Sizes: Creates multiple variants (thumbnail, medium, large) with proper
srcsetandsizesattributes. - Converts to Modern Formats: Produces WebP and AVIF versions for modern browsers, with JPEG fallback for older browsers.
- Build Optimization: Checks file modification times to avoid re-processing unchanged images.
This resulted in images that are 60-80% smaller than their originals without noticeable quality loss.
const sharp = require('sharp');
const fs = require('fs').promises;
const path = require('path');
async function processImage(inputPath, outputDir) {
const sizes = [
{ width: 400, suffix: 'thumb' },
{ width: 800, suffix: 'medium' },
{ width: 1200, suffix: 'large' },
];
// Modern formats + JPEG fallback
const formats = ['avif', 'webp', 'jpeg'];
const baseName = path.basename(inputPath, path.extname(inputPath));
for (const size of sizes) {
for (const format of formats) {
await sharp(inputPath)
.resize(size.width, null, { withoutEnlargement: true })
.toFormat(format, { quality: 85 })
.toFile(
path.join(outputDir, `${baseName}-${size.suffix}.${format}`)
);
}
}
}b. Sub-Second Page Rendering Strategy
To ensure the site feels instant, I focused on optimizing the critical rendering path:
- Critical CSS Extraction: Extracts and inlines CSS needed for above-the-fold content, eliminating render-blocking stylesheet requests.
- Lazy Loading: Uses native
loading="lazy"on images to defer off-screen content. - Asset Minification: All HTML, CSS, and JS are automatically minified during the build process.
c. Offline-First Reliability with a PWA
To make the site resilient to poor network conditions, I built it as a Progressive Web App (PWA):
- Custom Service Worker: Implements tailored caching strategies—Cache First for images and fonts, Stale-While-Revalidate for CSS/JS, and Network First for HTML pages to ensure fresh content.
- Cache Management: Automatic cache versioning and cleanup on deploy to prevent stale content.
This enables fast repeat visits and offline functionality for previously viewed pages.
d. Streamlined Developer Experience
A key goal was to make the site easy to update. I achieved this through:
- Eleventy's Data Cascade: Using Eleventy's file-based structure, adding a new photo is as simple as adding a new Markdown file with front matter. The build process handles the rest.
- Automation Scripts: Scripts for creating new posts (
mkpost.js) and optimizing images are integrated into npm commands, simplifying the content creation workflow.
Outcome & Impact
This project demonstrates that a media-heavy website can achieve high performance metrics without compromising on visual quality.
- Performance: Achieved Lighthouse scores of 98+ in Performance, Best Practices, and SEO. The site loads quickly on both desktop and mobile devices.
- User Experience: Fully responsive design with offline functionality for previously viewed content.
- Maintainability: Adding new photos is as simple as creating a new Markdown file—the build process handles the rest automatically.