Image Optimization Detection: Is This Site Wasting Bandwidth?
A practical Fusebox guide to image optimization detection.
Image Optimization Detection: Is This Site Wasting Bandwidth?
Published: January 2024
Reading time: 8 minutes
Images are usually the heaviest part of any website. A single unoptimized image can be larger than your entire JavaScript bundle. Here's how to detect optimization issues and why they matter.
The Image Weight Problem
Real Numbers from Popular Sites
E-commerce Homepage:
Total page size: 8.2MB
Images: 6.8MB (83%)
- Hero banner: 2.1MB (PNG!)
- Product images: 4.2MB (unoptimized JPEGs)
- Icons: 0.5MB (should be SVG)
News Article:
Total page size: 4.5MB
Images: 3.9MB (87%)
- Featured image: 1.8MB (4000x3000px displayed at 800x600)
- Inline images: 2.1MB (no lazy loading)
These sites are forcing users to download 5-10x more data than necessary.
How to Detect Image Issues
1. Quick Console Audit
// Paste this to analyze current page
(function imageAudit() {
const images = Array.from(document.images);
let totalSize = 0;
let issues = [];
images.forEach(img => {
// Get natural vs display size
const natural = img.naturalWidth * img.naturalHeight;
const display = img.clientWidth * img.clientHeight;
const ratio = natural / display;
if (ratio > 2) {
issues.push({
src: img.src,
natural: `${img.naturalWidth}x${img.naturalHeight}`,
display: `${img.clientWidth}x${img.clientHeight}`,
waste: `${((ratio - 1) * 100).toFixed(0)}% too large`
});
}
});
console.table(issues);
// Check formats
const formats = {};
images.forEach(img => {
const ext = img.src.split('.').pop().split('?')[0].toLowerCase();
formats[ext] = (formats[ext] || 0) + 1;
});
console.log('Image formats:', formats);
// Performance entries
const imageResources = performance.getEntriesByType('resource')
.filter(r => r.name.match(/\.(jpg|jpeg|png|gif|webp|avif)$/i));
imageResources.forEach(resource => {
totalSize += resource.transferSize || 0;
});
console.log(`Total image size: ${(totalSize / 1024 / 1024).toFixed(1)}MB`);
})();
2. Dimension Analysis
// Oversized images waste bandwidth
const oversizedImages = Array.from(document.images).filter(img => {
const displayed = img.clientWidth * img.clientHeight;
const actual = img.naturalWidth * img.naturalHeight;
return actual > displayed * 1.5; // 50% larger than needed
});
console.log(`Found ${oversizedImages.length} oversized images`);
3. Format Detection
// Check for modern formats
const images = performance.getEntriesByType('resource')
.filter(r => r.name.match(/\.(jpg|jpeg|png|gif|webp|avif)$/i));
const formats = {
legacy: 0, // JPG, PNG, GIF
modern: 0 // WebP, AVIF
};
images.forEach(img => {
if (img.name.match(/\.(webp|avif)$/i)) {
formats.modern++;
} else {
formats.legacy++;
}
});
console.log(`Modern formats: ${formats.modern}/${images.length}`);
Common Image Problems
1. Wrong Format for Content
PNG for Photos (Bad)
<img src="team-photo.png" alt="Our team">
<!-- 2.8MB PNG → should be 280KB JPEG -->
JPEG for Graphics (Bad)
<img src="logo.jpg" alt="Company logo">
<!-- Blurry edges, artifacts → should be SVG -->
Right Format Guide:
- Photos: JPEG, WebP, AVIF
- Graphics/Logos: SVG (scalable) or PNG
- Animations: Video (MP4) not GIF
- Icons: SVG or icon fonts
2. Serving Desktop Images to Mobile
The Problem:
<!-- Same image for all devices -->
<img src="hero-4000x2000.jpg" alt="Hero">
<!-- Mobile (375px): Downloads 4000px image -->
<!-- Tablet (768px): Downloads 4000px image -->
<!-- Desktop (1920px): Uses 4000px image -->
The Solution:
<picture>
<source media="(max-width: 640px)"
srcset="hero-640.webp"
type="image/webp">
<source media="(max-width: 1024px)"
srcset="hero-1024.webp"
type="image/webp">
<source srcset="hero-2048.webp"
type="image/webp">
<img src="hero-2048.jpg" alt="Hero">
</picture>
3. No Lazy Loading
Loading everything immediately:
<!-- Page has 50 images, all load immediately -->
<img src="image1.jpg">
<img src="image2.jpg">
<!-- ... 48 more -->
Smart lazy loading:
<!-- Above fold: Load immediately -->
<img src="hero.jpg" loading="eager">
<!-- Below fold: Load when needed -->
<img src="image2.jpg" loading="lazy">
<img src="image3.jpg" loading="lazy">
4. Missing Compression
Unoptimized vs Optimized:
Original photo.jpg: 3.2MB
After optimization: 320KB (90% smaller!)
Same visual quality to users
Real-World Examples
Example 1: Blog with Heavy Images
Found Issues:
{
"total_images": 23,
"total_size": "18.4MB",
"problems": {
"oversized": 19,
"wrong_format": 8,
"no_lazy_loading": 23,
"no_srcset": 23
}
}
Specific Problems:
author-photo.png: 890KB → Should be 45KB JPEG
screenshot1.png: 2.1MB → Should be 180KB JPEG
icon-set.png: 340KB → Should be 8KB SVG sprite
Impact: Page loads in 12 seconds on 4G
Example 2: E-commerce Product Gallery
Analysis:
// Main product image
{
file: "product-main.jpg",
dimensions: "4000x4000",
displayed: "600x600",
size: "3.8MB",
waste: "98.5% pixels not shown"
}
// Thumbnails
{
files: 8,
total_size: "4.2MB",
displayed_size: "100x100 each",
optimal_size: "~200KB total"
}
Fix Applied:
<!-- Responsive images -->
<img srcset="product-600.webp 600w,
product-1200.webp 1200w,
product-2400.webp 2400w"
sizes="(max-width: 600px) 100vw, 600px"
src="product-600.jpg"
loading="lazy">
Result: 3.8MB → 380KB (90% reduction)
Example 3: Restaurant Website
Hero Section Disaster:
hero-background.jpg:
- File size: 5.2MB
- Dimensions: 5472x3648
- Display area: 1920x600
- Visible portion: 10%
- Loading time: 8 seconds
Multiple Issues:
- Using photo dimensions for web
- No compression
- Loading full image for banner crop
- JPEG instead of WebP
Image Optimization Techniques
1. Modern Formats
WebP (25-35% smaller than JPEG):
<picture>
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Fallback for old browsers">
</picture>
AVIF (50% smaller than JPEG):
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Progressive enhancement">
</picture>
2. Responsive Images
srcset for Resolution:
<img srcset="small.jpg 1x, large.jpg 2x"
src="small.jpg"
alt="Retina support">
sizes for Viewport:
<img srcset="image-400.jpg 400w,
image-800.jpg 800w,
image-1200.jpg 1200w"
sizes="(max-width: 400px) 100vw,
(max-width: 800px) 50vw,
400px"
src="image-400.jpg">
3. Compression Levels
// Typical savings
const compression = {
'PNG': {
lossless: '10-30% smaller',
lossy: '60-80% smaller'
},
'JPEG': {
quality85: '40-60% smaller',
quality75: '60-80% smaller'
},
'WebP': {
lossless: '26% smaller than PNG',
lossy: '25-34% smaller than JPEG'
}
};
4. Lazy Loading Strategies
// Native lazy loading
<img loading="lazy" src="image.jpg">
// Intersection Observer (more control)
const images = document.querySelectorAll('img[data-src]');
const imageObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
imageObserver.unobserve(img);
}
});
});
images.forEach(img => imageObserver.observe(img));
Quick Optimization Checklist
Format Selection
- Photos in WebP/JPEG, not PNG
- Graphics/logos in SVG
- No BMP or TIFF on web
- GIFs → MP4 videos
Size Optimization
- Images sized for display
- Responsive images implemented
- Retina handled efficiently
- Compression applied
Loading Strategy
- Lazy loading enabled
- Critical images prioritized
- Progressive JPEG for large images
- Placeholder/blur while loading
Performance
- Total image weight < 1MB per page
- No single image > 500KB
- CDN serving images
- Browser caching configured
Detection Tools
Browser DevTools
1. Network tab → Filter: Img
2. Sort by size (largest first)
3. Check "Disable cache"
4. Look for:
- Red flags: > 500KB images
- Format: Avoid PNG for photos
- Dimensions vs display size
Lighthouse Report
Images section shows:
- Properly size images
- Serve images in next-gen formats
- Efficiently encode images
- Use lazy loading
Performance API
// Get image performance data
const images = performance.getEntriesByType('resource')
.filter(entry => entry.name.match(/\.(jpg|jpeg|png|gif|webp|avif)/i))
.sort((a, b) => b.transferSize - a.transferSize);
console.table(images.map(img => ({
url: img.name.split('/').pop(),
size: `${(img.transferSize / 1024).toFixed(0)}KB`,
time: `${img.duration.toFixed(0)}ms`
})));
The Business Impact
Real Numbers
- Amazon: 1 second delay = $1.6B lost sales/year
- Google: 0.5 second delay = 20% traffic drop
- Pinterest: 40% faster = 15% more signups
Your Impact
Before optimization:
- Image weight: 12MB
- Load time: 8.5s
- Bounce rate: 68%
After optimization:
- Image weight: 1.8MB (85% reduction)
- Load time: 2.1s
- Bounce rate: 32%
Result: 2x conversions
The Bottom Line
Image optimization is the easiest performance win:
- Huge impact (often 50-90% size reduction)
- Simple fixes (compression, formats, lazy load)
- Immediate results (faster loads, happier users)
- Better SEO (Core Web Vitals improvement)
Every unoptimized image is bandwidth stolen from your users.
Detect image optimization issues instantly: Fusebox analyzes all images for size, format, and loading issues while you browse. See optimization opportunities immediately. $29 one-time purchase.