feat: CI workflow for image resizing and optimization
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
Implement an automated image processing pipeline that generates optimized, responsive image variants during CI/CD builds.
## Motivation
- Large images slow down page loads and hurt SEO
- Manually resizing images for different breakpoints is tedious
- Modern formats (AVIF, WebP) provide significant size savings but need fallbacks
- Consistent image handling improves developer experience
## Technical Approach
### Core Decisions
| Decision | Choice | Rationale |
|----------|--------|-----------|
| Processing Tool | **Sharp** | Already installed, 10-50x faster than alternatives |
| Output Formats | AVIF, WebP, JPEG | AVIF (best compression), WebP (broad support), JPEG (fallback) |
| Storage | Git-tracked source, gitignored output | Reproducible builds, no external dependencies |
| Caching | Hash-based manifest | Skip unchanged images for incremental builds |
### Size Configurations
| Name | Width | Use Case |
|------|-------|----------|
| thumb | 150px | Thumbnails, related posts |
| small | 320px | Mobile portrait |
| medium | 640px | Tablet, small desktop |
| large | 1024px | Desktop content area |
| xl | 1400px | Full-width hero images |
| 2x | 2048px | High-DPI displays |
### Configuration File (`images.config.json`)
```json
{
"$schema": "https://schemas.arusty.dev/blog/images.config.schema.json",
"sourceDir": "src/assets/images",
"outputDir": "public/_images",
"formats": ["avif", "webp", "jpeg"],
"sizes": {
"thumb": { "width": 150 },
"small": { "width": 320 },
"medium": { "width": 640 },
"large": { "width": 1024 },
"xl": { "width": 1400 }
},
"quality": {
"avif": 65,
"webp": 80,
"jpeg": 80
}
}
```
## Implementation Tasks
### Phase 1: Core Infrastructure
- [ ] Create JSON schema for `images.config.json`
- [ ] Create `scripts/process-images.ts` using Sharp
- [ ] Implement hash-based caching with manifest file
- [ ] Add `npm run images` script
- [ ] Integrate into `npm run build`
### Phase 2: GitHub Actions Integration
- [ ] Add image processing step to workflow
- [ ] Configure `public/_images/` caching
- [ ] Add cache restoration from previous builds
- [ ] Add processing metrics logging
### Phase 3: Astro Integration
- [ ] Create `` component with srcset generation
- [ ] Create image utility functions for path resolution
- [ ] Update content schema with image field types
- [ ] Document usage with examples
### Phase 4: Optimization
- [ ] Add parallel processing for multiple images
- [ ] Add error handling and clear messages
- [ ] Add `--dry-run` mode
- [ ] Add verbose logging option
## File Structure
```
blog/
├── images.config.json
├── scripts/
│ └── process-images.ts
├── src/
│ ├── assets/
│ │ ├── images/ # Source (git tracked)
│ │ └── .image-manifest.json
│ └── components/
│ └── Picture.astro
└── public/
└── _images/ # Generated (gitignored)
```
## Dependencies
- `sharp` - Already installed
- `glob` - For file discovery (add as devDependency)
## Future Enhancements
- [ ] Cloudflare Image Resizing for on-demand processing
- [ ] R2 storage for generated images
- [ ] Blur placeholder (LQIP) generation
- [ ] Art direction support for different crops per breakpoint
## Labels
enhancement, infrastructure, images
Contributor guide
Assessment
This issue has not been assessed yet.