Automatic image optimization in CampsiteJS - convert JPG/PNG to modern WebP and AVIF formats with configurable quality settings.
CampsiteJS includes built-in photo compression that automatically converts your images to modern, optimized formats during the build process. This feature dramatically reduces file sizes while maintaining visual quality, resulting in faster page loads and better user experience.
Overview
Photo compression in CampsiteJS is powered by the Sharp library, providing high-performance image processing with minimal configuration. When enabled, the build process automatically:
- Converts JPG/PNG images to WebP and/or AVIF formats
- Optimizes file sizes while maintaining quality
- Preserves original images (optional)
- Processes images in the
public/directory during build
Configuration
Photo compression is configured in your campsite.config.js file:
Basic Configuration
export default {
// ... other config
compressPhotos: true,
compressionSettings: {
quality: 80,
formats: ['.webp', '.avif'],
inputFormats: ['.jpg', '.jpeg', '.png'],
preserveOriginal: true
}
};
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
compressPhotos |
boolean |
false |
Enable/disable photo compression |
quality |
number |
80 |
Compression quality (0-100). Higher = better quality, larger file size |
formats |
array |
['.webp'] |
Output formats. Options: '.webp', '.avif' |
inputFormats |
array |
['.jpg', '.jpeg', '.png'] |
Source image formats to process |
preserveOriginal |
boolean |
true |
Keep original images alongside compressed versions |
Usage Examples
WebP Only (Fast, Good Compatibility)
export default {
compressPhotos: true,
compressionSettings: {
quality: 80,
formats: ['.webp'],
inputFormats: ['.jpg', '.jpeg', '.png'],
preserveOriginal: true
}
};
WebP + AVIF (Best Optimization)
export default {
compressPhotos: true,
compressionSettings: {
quality: 80,
formats: ['.webp', '.avif'],
inputFormats: ['.jpg', '.jpeg', '.png'],
preserveOriginal: true
}
};
Maximum Quality (Larger Files)
export default {
compressPhotos: true,
compressionSettings: {
quality: 95,
formats: ['.webp'],
inputFormats: ['.jpg', '.jpeg', '.png'],
preserveOriginal: true
}
};
Replace Originals (Save Space)
export default {
compressPhotos: true,
compressionSettings: {
quality: 80,
formats: ['.webp'],
inputFormats: ['.jpg', '.jpeg', '.png'],
preserveOriginal: false // Removes original files
}
};
Build Process
When you run camper build, compressed images are automatically generated:
camper build
Example output:
๐๏ธ Building your Campsite...
๐ Processing pages... (23 pages)
๐จ Processing layouts... (5 layouts)
๐ธ Compressing photos...
โ
hero.jpg โ hero.webp (saved 245 KB)
โ
hero.jpg โ hero.avif (saved 312 KB)
โ
team-photo.png โ team-photo.webp (saved 189 KB)
โ
Build complete! Output: ./dist/
Using Compressed Images in HTML
With Picture Element (Recommended)
The <picture> element provides the best browser support and fallback options:
<picture>
<!-- Modern formats for supporting browsers -->
<source srcset="/images/hero.avif" type="image/avif">
<source srcset="/images/hero.webp" type="image/webp">
<!-- Fallback for older browsers -->
<img src="/images/hero.jpg" alt="Hero image">
</picture>
Simple WebP with Fallback
<picture>
<source srcset="/images/photo.webp" type="image/webp">
<img src="/images/photo.jpg" alt="Description">
</picture>
Responsive Images
Combine with responsive image techniques:
<picture>
<source
srcset="/images/banner-small.webp 600w,
/images/banner-medium.webp 1200w,
/images/banner-large.webp 1800w"
type="image/webp">
<img
src="/images/banner.jpg"
srcset="/images/banner-small.jpg 600w,
/images/banner-medium.jpg 1200w,
/images/banner-large.jpg 1800w"
sizes="(max-width: 600px) 600px,
(max-width: 1200px) 1200px,
1800px"
alt="Banner">
</picture>
Format Comparison
WebP
- Browser Support: 95%+ (all modern browsers)
- Compression: ~25-35% smaller than JPEG
- Speed: Fast encoding/decoding
- Use Case: Best for most projects
AVIF
- Browser Support: ~85% (Chrome, Opera, Firefox, Safari 16+)
- Compression: ~50% smaller than JPEG
- Speed: Slower encoding
- Use Case: Cutting-edge optimization
Recommended Strategy
Use both WebP and AVIF with a fallback:
formats: ['.webp', '.avif']
This ensures:
- Modern browsers get ultra-optimized AVIF
- Older browsers get efficient WebP
- Legacy browsers fall back to original format
Quality Guidelines
| Quality | File Size | Use Case |
|---|---|---|
| 95-100 | Largest | Photography portfolios, professional work |
| 85-90 | Large | High-quality images where detail matters |
| 80 | Balanced | Default - Good for most websites |
| 70-75 | Small | Blog posts, thumbnails |
| 60-65 | Smallest | Background images, decorative elements |
Performance Tips
1. Directory Organization
Keep images organized in public/images/:
public/
images/
hero.jpg
team/
member-1.jpg
member-2.jpg
products/
product-1.png
2. Selective Compression
To skip certain images, use the excludeFiles option:
export default {
compressPhotos: true,
excludeFiles: ['logo.png', 'icon-*.png'], // Skip these files
compressionSettings: {
// ...
}
};
3. Pre-sized Images
For best results, resize images before adding them to your project:
- Hero images: 1920px wide
- Blog images: 1200px wide
- Thumbnails: 400px wide
4. Lazy Loading
Combine with lazy loading for optimal performance:
<picture>
<source srcset="/images/hero.webp" type="image/webp">
<img
src="/images/hero.jpg"
alt="Hero"
loading="lazy">
</picture>
Troubleshooting
Compression Not Working
Check your config:
compressPhotos: true, // Must be true
Verify Sharp installation:
npm install sharp --save-dev
Images Not Appearing
- Ensure images are in
public/directory - Check file extensions match
inputFormats - Verify build completed without errors
Large File Sizes
- Lower the
qualitysetting (try 70-75) - Use both
.webpand.avifformats - Pre-resize images before adding to project
Examples
Photo Gallery
<div class="gallery">
<picture>
<source srcset="/images/gallery/photo1.webp" type="image/webp">
<img src="/images/gallery/photo1.jpg" alt="Photo 1" loading="lazy">
</picture>
<picture>
<source srcset="/images/gallery/photo2.webp" type="image/webp">
<img src="/images/gallery/photo2.jpg" alt="Photo 2" loading="lazy">
</picture>
</div>
Blog Post with Featured Image
---
title: My Blog Post
featuredImage: /images/blog/post-hero.jpg
---
<article>
<picture>
<source srcset="{{ featuredImage | replace('.jpg', '.avif') }}" type="image/avif">
<source srcset="{{ featuredImage | replace('.jpg', '.webp') }}" type="image/webp">
<img src="{{ featuredImage }}" alt="{{ title }}" class="featured-image">
</picture>
<h1>{{ title }}</h1>
{{ content | safe }}
</article>
Best Practices
- Always use the picture element for proper browser support
- Set quality to 80 for a good balance (default)
- Use both WebP and AVIF for maximum optimization
- Keep originals during development (
preserveOriginal: true) - Add width/height attributes to prevent layout shift
- Use lazy loading for below-the-fold images
- Test on multiple devices to ensure quality is acceptable
Additional Resources
- Sharp Documentation
- WebP Browser Support
- AVIF Browser Support
- MDN: Picture Element
- Image Optimization Guide
Next Steps:
- File Exclusion - Skip specific files during build
- Configuration - Advanced config options
- Deploying - Launch your optimized site