Image optimization in the popup¶
Guide type: Reference
Difficulty: Advanced
Applies to: SmartSize winner popup
SmartSize uses a comprehensive image optimization strategy inside the popup to reduce bandwidth, improve Core Web Vitals, and maintain a responsive experience across devices.
This reference describes the optimization strategies, components, and utilities that handle product images in the quiz and size chart popups.
Optimization strategies¶
Lazy loading¶
All images inside the popup use the loading="lazy" attribute. Images below the fold or inside collapsed steps are deferred until the user scrolls or navigates to them.
Benefits:
- Reduces initial page load time
- Saves bandwidth for users who do not scroll to images
- Improves Core Web Vitals (LCP, CLS)
Applies to:
- Multiple choice option images
- Bra size step images
- Size chart images
- Product thumbnails
Explicit image dimensions¶
Every image has explicit width and height attributes. The browser reserves space before the image loads, preventing layout shift.
Benefits:
- Prevents layout shifts (CLS improvement)
- Allows browser to reserve space before image loads
- Improves rendering performance
Example:
Image preloading¶
Critical images are preloaded using <link rel="preload"> when the popup opens or when a step becomes active. Non-critical images remain lazy-loaded.
Preloaded images:
- Button icons
- Product images on the winner screen
- Quiz step images when the step is active
- Bra size step images
Benefits:
- Critical images load faster
- Reduces perceived loading time
- Improves user experience for key interactions
Error handling¶
Every image has an onError handler. If an image fails to load, it is hidden gracefully rather than showing a broken placeholder.
Benefits:
- Graceful degradation when images fail to load
- Prevents broken image placeholders
- Better user experience
Modern image formats¶
SmartSize serves images in WebP format where supported. The image utilities include detection logic for AVIF support and will upgrade when the browser supports it.
Benefits:
- Smaller file sizes (25–35% smaller than JPEG)
- Better compression
- Faster loading times
Components and utilities¶
OptimizedImage component¶
A reusable Preact component that wraps all optimization best practices:
<OptimizedImage
src="image.webp"
alt="Size guide illustration"
width={80}
height={80}
preload={true}
fallbackSrc="fallback.jpg"
onLoad={() => console.log('Image loaded')}
onError={() => console.log('Image failed')}
/>
Features:
- Automatic lazy loading (
loading="lazy"by default) - Loading state management
- Error handling with fallbacks
- Optional preloading
- Smooth opacity transitions
Image optimization utilities¶
Location: src/utils/imageOptimization.ts
optimizeImageUrl(url, options)¶
Adds Shopify CDN optimization parameters to an image URL.
generateSrcSet(baseUrl, widths, options)¶
Creates responsive image srcset attributes for different viewport sizes.
const srcset = generateSrcSet(baseUrl, [320, 640, 960], {
format: 'webp',
quality: 85
});
// Returns: "url_320.webp 320w, url_640.webp 640w, url_960.webp 960w"
preloadImage(url) / preloadImages(urls)¶
Preloads individual or multiple images programmatically.
getSupportedFormats()¶
Detects browser support for modern image formats.
measureImageLoadTime(url)¶
Measures image load performance for monitoring.
const loadTime = await measureImageLoadTime(imageUrl);
console.log(`Image loaded in ${loadTime}ms`);
Performance impact¶
Before optimization¶
- ❌ No lazy loading
- ❌ Missing image dimensions
- ❌ No error handling
- ❌ Limited preloading
- ❌ No format optimization
After optimization¶
- ✅ Lazy loading on all images
- ✅ Explicit dimensions preventing layout shifts
- ✅ Comprehensive error handling
- ✅ Strategic preloading of critical images
- ✅ WebP format usage
- ✅ Performance monitoring utilities
- ✅ Reusable optimized components
Expected performance gains¶
| Metric | Improvement |
|---|---|
| LCP (Largest Contentful Paint) | 20–30% faster |
| CLS (Cumulative Layout Shift) | 50–70% reduction |
| Bandwidth usage | 25–35% reduction (WebP vs JPEG) |
| Perceived performance | Significant improvement |
Implementation by component¶
MultipleChoiceStep¶
- Preloads all step images when the component mounts
- Lazy loading for individual option images
- Error handling with graceful degradation
- Explicit dimensions for all images
BraSizeStep¶
- Preloads bra size step images
- Lazy loading for method selection images
- Error handling for all images
- Optimized image dimensions
Main app component¶
- Preloads critical images (button icon, product image)
- Lazy loading for modal images
- Error handling for all images
- Optimized loading strategy
Future enhancements¶
| Enhancement | Description |
|---|---|
| AVIF format support | Automatic detection and usage when supported. Further 20–30% size reduction over WebP. |
Responsive srcset and sizes |
Serve different image sizes based on device pixel density and viewport. |
| Progressive loading | Show low-quality placeholders first, then sharpen. |
| Server-side compression | Automatic quality adjustment based on content type. |
| Edge caching | Leverage Shopify CDN features for faster global delivery. |
Best practices¶
- Always use explicit dimensions for images.
- Implement lazy loading for non-critical images.
- Preload critical images that are above the fold or immediately visible.
- Use modern formats (WebP, AVIF) when possible.
- Handle errors gracefully with fallbacks.
- Monitor performance and optimize based on metrics.
- Use responsive images for different screen sizes.
- Optimize image quality based on use case.
Testing¶
Manual testing¶
- Check image loading in different network conditions (Fast 3G, Slow 3G)
- Verify lazy loading behavior in browser DevTools Network panel
- Test error handling by blocking image URLs
- Monitor layout shifts using DevTools Performance panel
Automated testing¶
- Lighthouse performance audits
- Core Web Vitals monitoring
- Image optimization validation
Related articles¶
- CSS customization reference — Styling the popup and buttons
- Styling resilience and conflict prevention — Preventing theme CSS conflicts