Problem
Baseline artifacts store full-page PNG screenshots which can be large (often 2-5 MB per route). This increases:
- GitHub Actions artifact storage costs
- Upload/download times for baseline artifacts
- CI runtime (artifact upload is often the slowest step)
Proposal
Add optional PNG compression to reduce screenshot file sizes with minimal visual impact.
Config
{
"screenshots": {
"compression": "none" | "fast" | "aggressive"
}
}
| Mode |
Description |
Typical savings |
none (default) |
No compression, original PNG output |
0% |
fast |
Lossy compression at quality 0.8 |
~40-60% |
aggressive |
Lossy compression at quality 0.5 |
~70-80% |
Implementation
Use pngquant (the de-facto standard for PNG compression) via its Node bindings or as a subprocess.
Implementation Plan
1. Config validation (lib/snapdrift-config.mjs)
- Add
screenshots.compression field to config validation
- Validate: must be one of
none, fast, aggressive
- Default:
none (no change to existing behavior)
2. Capture flow (lib/capture-routes.mjs)
- After screenshot capture, apply compression based on config
pngquant via subprocess: pngquant --quality=80-90 --speed=1 --output <out> <in> for fast mode
pngquant --quality=50-70 --speed=1 --output <out> <in> for aggressive mode
- Handle missing pngquant gracefully: log a warning and skip compression
3. Dependency
- Add
pngquant-bin as an optional dependency (or sharp which includes PNG compression)
- In the action YAML, install the dependency before capture
4. Type definitions
- Add
screenshots?: { compression?: "none" | "fast" | "aggressive" } to VisualRegressionConfig
5. Tests
capture-routes.test.js: test that compression mode is applied
- Test that missing pngquant logs a warning but doesn't fail
- Test that
compression: none produces identical output (no regression)
6. Documentation
docs/contracts.md: add screenshots.compression field
docs/integration-guide.md: add compression example with typical savings
CHANGELOG.md: add entry under Unreleased
7. GitHub Actions updates
actions/baseline/action.yml: add optional install-pngquant input (default: true)
- Install pngquant in the action step when compression is enabled
Acceptance Criteria
Problem
Baseline artifacts store full-page PNG screenshots which can be large (often 2-5 MB per route). This increases:
Proposal
Add optional PNG compression to reduce screenshot file sizes with minimal visual impact.
Config
{ "screenshots": { "compression": "none" | "fast" | "aggressive" } }none(default)fastaggressiveImplementation
Use
pngquant(the de-facto standard for PNG compression) via its Node bindings or as a subprocess.Implementation Plan
1. Config validation (
lib/snapdrift-config.mjs)screenshots.compressionfield to config validationnone,fast,aggressivenone(no change to existing behavior)2. Capture flow (
lib/capture-routes.mjs)pngquantvia subprocess:pngquant --quality=80-90 --speed=1 --output <out> <in>for fast modepngquant --quality=50-70 --speed=1 --output <out> <in>for aggressive mode3. Dependency
pngquant-binas an optional dependency (orsharpwhich includes PNG compression)4. Type definitions
screenshots?: { compression?: "none" | "fast" | "aggressive" }toVisualRegressionConfig5. Tests
capture-routes.test.js: test that compression mode is appliedcompression: noneproduces identical output (no regression)6. Documentation
docs/contracts.md: addscreenshots.compressionfielddocs/integration-guide.md: add compression example with typical savingsCHANGELOG.md: add entry under Unreleased7. GitHub Actions updates
actions/baseline/action.yml: add optionalinstall-pngquantinput (default: true)Acceptance Criteria
screenshots.compressionfieldnpm run cipasses on the branch