How to Prevent Re-encoding Unchanged AVIF Images
AVIF offers superior compression efficiency for modern web applications, but its encoding process requires significant CPU resources and time. In static site generators and automated CI/CD pipelines, re-encoding every image on every build causes massive build-time bottlenecks and inflates server costs. This article explains how developers can prevent the redundant processing of unchanged AVIF images by using content hashing, persistent caching, timestamp validation, and offloaded image pipelines.
Implement Content-Based Hashing
The most reliable method to detect file changes is generating a cryptographic hash (such as MD5 or SHA-256) of the source image buffer.
- Generate a hash from the raw image file before passing it to encoders like Sharp or Libavif.
- Maintain a JSON manifest or metadata file that pairs the original file's hash with its generated AVIF output path.
- During a build, check if the source file's current hash matches the recorded hash in the manifest. If it matches and the output AVIF file exists on disk, skip encoding.
This method guarantees that even if a file's metadata or timestamp changes, it will not be re-encoded unless the image content itself is modified.
Persist Build Caches in CI/CD
Local build caching fails in ephemeral CI/CD environments like GitHub Actions, GitLab CI, or Netlify, where every run begins with a fresh virtual environment.
To maintain efficiency:
- Configure your CI system to cache the generated output folder and your manifest file between runs.
- Use key-based caching where the cache key incorporates the lockfile and the image directory state.
- Restore the cache before the build script executes, ensuring the image processor finds previously converted AVIF files intact.
Use File Modification Timestamps for Local Builds
For simple setups or command-line scripts using tools like Make,
rsync, or custom Node.js scripts, comparing modification
timestamps (mtime) is an effective, low-overhead
approach.
- Compare the
mtimeof the source image against themtimeof the target.aviffile. - If the target exists and is newer than the source, skip processing.
- Note that git does not track file modification times natively, so this approach is best suited for local development environments rather than distributed CI environments.
Decouple Image Processing from Site Builds
Embedding heavy AVIF compression directly into the main website build step causes unnecessary slowdowns. Decoupling the workflows prevents routine code changes from triggering image re-encoding.
- Dedicated Image Workflows: Run image optimization as an isolated Git hook, a separate pull request action, or a standalone pre-commit step. When new images are committed, generate the AVIF versions once and check them directly into the repository or an asset storage bucket (such as AWS S3).
- On-Demand Processing via Image CDNs: Shift the conversion overhead away from the build entirely by using an image transformation service (such as Cloudflare Images, Fastly, or self-hosted Imgproxy). These services convert images to AVIF at the edge upon the first user request and cache the result indefinitely, eliminating the need to process images during the site build.
Leverage Framework-Native Caching
Modern static site generators and frameworks provide built-in caching for asset transformations:
- Next.js: The built-in image optimization API
automatically optimizes images on-demand and caches them in the
.next/cachedirectory. Persisting this folder across builds prevents duplicate processing. - Astro: The
@astrojs/imageand core image assets use content-addressable storage inside the build cache directory. - Eleventy: Plugins like
eleventy-imgcache source images and their transformed formats to disk based on the source path and options, skipping unchanged images across successive runs.
Ensure your configuration preserves the respective framework cache directories between successive deployments.