gotodev-image-optimizer
v0.1.2
Published
Content-aware, device-adaptive image optimizer for React + Vite projects
Readme
gotodev-image-optimizer
Content-aware, device-adaptive image optimizer for Vite + React.
Surpasses Next.js Image in perceptual quality at equal or smaller file sizes.
How it works
Build time (Vite plugin)
Every image is divided into 64×64 tiles and analyzed:
- Analyze — per-tile Shannon entropy, Sobel edge density, and skin-tone ratio produce an importance map
- Weight — top 30% most-important tiles drive 70% of the quality decision; center-bias and edge-bonuses refine it
- Preprocess — high-importance tiles are selectively sharpened (with overlapped boundaries to prevent seams)
- Encode — each tier/variant is encoded at the perceptually-weighted quality; SSIM auto-tune finds the Pareto-optimal quality/size point
- Emit — manifest with variants, tiers, LQIP placeholders, and SRI hashes is embedded in the module
Runtime (GImage component)
- Fingerprint — reads
effectiveType,deviceMemory,hardwareConcurrency,devicePixelRatio,saveData - Tier — scoring algorithm selects
ultra/high/medium/lowper device capability - Format —
<picture>with AVIF, WebP, and JPEG sources - Load — IntersectionObserver with scroll-velocity-adaptive preload distance (600–3000px)
- Placeholder — blur-up CSS transition from 32×32 WebP base64 to full image
Features
Perceptually-optimized quality — 64×64 tile saliency drives quality per region. Faces, text, and detail get higher quality; backgrounds compress harder.
Saliency-driven preprocessing — important tiles are sharpened before encoding, preserving detail where it matters.
Skin-tone face detection — automatic quality boost around skin-colored regions. Zero extra dependencies.
SSIM auto-tune — finds the lowest quality where SSIM >= 0.97, saving 20–40% file size with no visible loss.
Device-adaptive delivery — runtime fingerprinting selects the optimal quality tier for each device.
Automatic format conversion — AVIF, WebP, and JPEG sources in a <picture> element.
Predictive lazy loading — scroll velocity sampling dynamically adjusts the preload distance.
Blur-up placeholders — 32×32 WebP base64 with CSS fade-in.
CLS prevention — fixed-aspect-ratio container from image metadata.
Install
npm install gotodev-image-optimizerUsage
Vite plugin
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import gotodevImageOptimizer from 'gotodev-image-optimizer/vite-plugin'
export default defineConfig({
plugins: [
react(),
gotodevImageOptimizer(),
],
})React component
import GImage from 'gotodev-image-optimizer'
import hero from './hero.jpg'
function Page() {
return (
<GImage
src={hero}
alt="Hero banner"
priority
sizes="(max-width: 768px) 100vw, 50vw"
/>
)
}All standard <img> props work: className, style, onLoad, onError, loading, etc.
Options
Plugin options
gotodevImageOptimizer({
tiers?: Partial<Record<QualityTier, TierConfig>>
adaptive?: boolean // default: true
autoTune?: boolean // default: true
preprocess?: boolean // default: true — sharpen important tiles before encoding
faceDetection?: boolean // default: true — boost quality around skin tones
formats?: OutputFormat[] // default: ['avif', 'webp', 'jpeg']
maxFileSize?: number // default: 52_428_800 (50MB)
verbose?: boolean // default: false
})GImage props
interface GImageProps {
src: string | ImageMetadata // import result or metadata object
alt: string
priority?: boolean // eager load + fetchPriority='high'
sizes?: string // default: '100vw'
disableAdaptive?: boolean // always deliver highest quality
placeholder?: 'blur' | 'none' // default: 'blur'
onLoad?: () => void
onError?: () => void
// + all standard img props (className, style, loading, etc.)
}Comparison: next/image vs GImage
| Aspect | next/image | GImage | |---|---|---| | Quality strategy | Uniform (e.g. 75) | Perceptually-weighted — important regions drive quality | | Preprocessing | None | Saliency-guided sharpen — detail preserved where it matters | | Face/subject detection | None | Skin-tone heuristic — quality boost on faces | | SSIM auto-tune | None | Smallest file at SSIM >= 0.97 | | Device adaptation | Responsive srcSet only | Runtime tier switching — CPU/memory/connection-aware | | Predictive loading | Fixed threshold | Velocity-adaptive — faster scroll = bigger preload zone | | Format pipeline | AVIF/WebP/JPEG | Same + skin detection + selectable preprocessor |
Requirements
- Node.js >= 22
- Vite >= 7
- React >= 19
License
MIT
