4. Image Optimization
Изображения — это 60-80% веса большинства веб-страниц. Оптимизация картинок — самое быстрое ROI в веб-производительности.
Современные форматы
Заголовок раздела «Современные форматы»| Формат | Сжатие | Прозрачность | Анимация | Поддержка |
|---|---|---|---|---|
| JPEG | Lossy | ❌ | ❌ | 99% |
| PNG | Lossless | ✅ | ❌ | 99% |
| WebP | Lossy/Lossless | ✅ | ✅ | 97% |
| AVIF | Lossy | ✅ | ✅ | 90% |
| SVG | Vector | ✅ | ✅ | 99% |
Правило: WebP на 30% легче JPEG, AVIF на 50% легче JPEG при том же качестве.
HTML: Современные подходы
Заголовок раздела «HTML: Современные подходы»<picture> — адаптивные форматы
Заголовок раздела «<picture> — адаптивные форматы»<picture> <!-- AVIF для поддерживающих браузеров --> <source srcset="/hero.avif" type="image/avif"> <!-- WebP как fallback --> <source srcset="/hero.webp" type="image/webp"> <!-- JPEG как последний fallback --> <img src="/hero.jpg" alt="Hero image" width="800" height="600"></picture>Адаптивные изображения через srcset
Заголовок раздела «Адаптивные изображения через srcset»<!-- Разные размеры для разных экранов --><img src="/photo-800.jpg" srcset=" /photo-400.jpg 400w, /photo-800.jpg 800w, /photo-1200.jpg 1200w, /photo-2400.jpg 2400w " sizes=" (max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px " alt="Responsive photo" width="800" height="600">Lazy Loading
Заголовок раздела «Lazy Loading»<!-- Нативный lazy loading (поддержка 92%+) --><img src="photo.jpg" loading="lazy" alt="Photo">
<!-- Не ленивая загрузка для первого экрана! --><img src="hero.jpg" loading="eager" fetchpriority="high" alt="Hero">CSS Background Images
Заголовок раздела «CSS Background Images»/* ✅ Адаптивные фоновые изображения */.hero { background-image: url('/hero-800.jpg');}
@media (min-width: 800px) { .hero { background-image: url('/hero-1600.jpg'); }}
/* ✅ WebP с fallback через @supports */@supports (background-image: url('/test.webp')) { .hero { background-image: url('/hero.webp'); }}Next.js Image Component
Заголовок раздела «Next.js Image Component»import Image from 'next/image';
// ✅ Автоматическая оптимизация: WebP, lazy, sizingfunction Hero() { return ( <Image src="/hero.jpg" alt="Hero" width={800} height={600} priority // Для LCP элемента quality={85} // Качество 0-100 placeholder="blur" // Blur placeholder /> );}
// ✅ Fill mode для адаптивных контейнеровfunction Cover() { return ( <div style={{ position: 'relative', aspectRatio: '16/9' }}> <Image src="/cover.jpg" alt="Cover" fill sizes="(max-width: 768px) 100vw, 50vw" style={{ objectFit: 'cover' }} /> </div> );}Инструменты оптимизации
Заголовок раздела «Инструменты оптимизации»Sharp (Node.js)
Заголовок раздела «Sharp (Node.js)»const sharp = require('sharp');
// Конвертация и сжатиеawait sharp('input.jpg') .resize(800, 600, { fit: 'inside', withoutEnlargement: true }) .webp({ quality: 85 }) .toFile('output.webp');
// Создание нескольких размеровconst sizes = [400, 800, 1200, 2400];for (const width of sizes) { await sharp('hero.jpg') .resize(width) .webp({ quality: 85 }) .toFile(`hero-${width}.webp`);}Squoosh (CLI)
Заголовок раздела «Squoosh (CLI)»npx @squoosh/cli --webp '{"quality":85}' *.jpgnpx @squoosh/cli --avif '{"cqLevel":33}' *.jpgImageMagick
Заголовок раздела «ImageMagick»# Конвертация в WebPconvert input.jpg -quality 85 output.webp
# Resize + optimizeconvert input.jpg -resize 800x600> -strip -quality 85 output.jpg
# Batch conversionmogrify -format webp -quality 85 *.jpgCSS: Aspect Ratio и объекты
Заголовок раздела «CSS: Aspect Ratio и объекты»/* ✅ Предотвращаем CLS — всегда задаём размеры */.image-container { aspect-ratio: 16 / 9; overflow: hidden; background: #f0f0f0; /* Placeholder */}
.image-container img { width: 100%; height: 100%; object-fit: cover; object-position: center;}
/* ✅ LQIP (Low Quality Image Placeholder) */.image-with-lqip { background-image: url('data:image/jpeg;base64,...'); /* tiny 10px version */ background-size: cover; filter: blur(10px); transition: filter 0.3s;}.image-with-lqip.loaded { filter: none;}Sprite CSS (для иконок)
Заголовок раздела «Sprite CSS (для иконок)»/* Один файл = один запрос */.icon { width: 32px; height: 32px; background-image: url('/sprite.png'); }.icon-home { background-position: 0 0; }.icon-user { background-position: -32px 0; }.icon-settings { background-position: -64px 0; }Лучшее решение для иконок — SVG sprite:
<svg style="display: none"> <symbol id="icon-home" viewBox="0 0 24 24"> <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/> </symbol></svg>
<!-- Использование --><svg class="icon"><use href="#icon-home"/></svg>