Serving same 4K image to mobile users? Picture element lets you serve different images per device, saving 80% bandwidth and loading 3x faster.
The Old Way – One Image for All:
<img src="hero-4k.jpg" alt="Hero" /> <!-- Problems: - Mobile downloads 5MB 4K image - Only displays 800px wide on phone - Wasted 80% of bandwidth - 5 second load time on mobile -->
Better – srcset Attribute:
<img
src="hero-1x.jpg"
srcset="hero-1x.jpg 1x, hero-2x.jpg 2x, hero-3x.jpg 3x"
alt="Hero"
/>
<!-- Browser picks based on screen density
- 1x: Standard displays (1920×1080)
- 2x: Retina displays
- 3x: High-end mobile
-->
Best – Picture Element (Full Control):
<picture>
<!-- Mobile: small image -->
<source
media="(max-width: 480px)"
srcset="hero-mobile.jpg"
/>
<!-- Tablet: medium image -->
<source
media="(max-width: 1024px)"
srcset="hero-tablet.jpg"
/>
<!-- Desktop: large image -->
<source
media="(min-width: 1025px)"
srcset="hero-desktop.jpg"
/>
<!-- Fallback for old browsers -->
<img src="hero-desktop.jpg" alt="Hero" />
</picture>
<!-- Result:
Mobile (480px): Downloads 200KB image
Tablet (1024px): Downloads 500KB image
Desktop (1920px): Downloads 1.5MB image
= Smart bandwidth usage
-->
Advanced – Modern Image Formats:
<picture>
<!-- AVIF (best compression, newest) -->
<source type="image/avif" srcset="hero.avif" />
<!-- WebP (great compression, widely supported) -->
<source type="image/webp" srcset="hero.webp" />
<!-- JPEG (fallback for old browsers) -->
<img src="hero.jpg" alt="Hero" />
</picture>
<!-- Browser picks best format it supports:
Chrome 90+: Uses AVIF (70% smaller than JPEG)
Chrome 80+: Uses WebP (30% smaller than JPEG)
Old browsers: Uses JPEG
-->
Combine Both – Format AND Size:
<picture>
<!-- Mobile AVIF -->
<source
media="(max-width: 480px)"
type="image/avif"
srcset="hero-mobile.avif"
/>
<!-- Mobile WebP -->
<source
media="(max-width: 480px)"
type="image/webp"
srcset="hero-mobile.webp"
/>
<!-- Mobile JPEG -->
<source
media="(max-width: 480px)"
srcset="hero-mobile.jpg"
/>
<!-- Desktop AVIF -->
<source
media="(min-width: 1025px)"
type="image/avif"
srcset="hero-desktop.avif"
/>
<!-- Desktop WebP -->
<source
media="(min-width: 1025px)"
type="image/webp"
srcset="hero-desktop.webp"
/>
<!-- Fallback -->
<img src="hero-desktop.jpg" alt="Hero" />
</picture>
Art Direction – Different Crops:
<picture>
<!-- Mobile: Portrait crop (vertical) -->
<source
media="(max-width: 480px)"
srcset="hero-portrait.jpg"
/>
<!-- Tablet: Square crop -->
<source
media="(max-width: 1024px)"
srcset="hero-square.jpg"
/>
<!-- Desktop: Landscape crop (horizontal) -->
<source
media="(min-width: 1025px)"
srcset="hero-landscape.jpg"
/>
<img src="hero-landscape.jpg" alt="Hero" />
</picture>
<!-- Use case: Hero images where composition matters
Mobile: Show person's face (vertical crop)
Desktop: Show full scene (horizontal crop)
-->
Lazy Loading with Picture:
<picture>
<source
media="(max-width: 480px)"
srcset="hero-mobile.webp"
type="image/webp"
/>
<img
src="hero-desktop.jpg"
alt="Hero"
loading="lazy" <!-- Native lazy load -->
/>
</picture>
<!-- Images below fold don't load until user scrolls -->
Performance Comparison:
Same image (1920×1080 hero photo): Single JPEG (4K optimized): - File size: 2.5 MB - Mobile load time: 8 seconds (3G) - Desktop load time: 1.2 seconds (WiFi) Picture element with WebP + responsive sizes: - Mobile: 180 KB (94% smaller!) - Tablet: 450 KB - Desktop WebP: 820 KB (67% smaller!) - Mobile load time: 1.5 seconds (3G) - Desktop load time: 0.4 seconds = 5-6x faster on mobile!
Browser Support:
Picture element: 98% (all modern browsers) AVIF: 85% (Chrome 85+, Firefox 93+, Safari 16+) WebP: 97% (all except IE) Always include JPEG fallback for <2% old browsers
