← Назад к вопросам
Как картинки загружаются на страницу?
1.3 Junior🔥 181 комментариев
#Браузер и сетевые технологии
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как картинки загружаются на страницу: полный процесс
Загрузка изображений - ключевой фактор производительности. Разберу весь процесс от браузера до экрана пользователя.
1. Парсинг HTML и обнаружение изображения
Браузер встречает <img> тег:
<img src="/images/photo.jpg" alt="My photo" width="800" height="600">
Браузер:
- Парсит HTML
- Видит
<img src="..."> - Извлекает URL из атрибута
src - Создаёт объект Image в памяти
2. Запрос на загрузку
Браузер делает HTTP GET запрос:
GET /images/photo.jpg HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0...
Accept: image/webp, image/apng, image/svg+xml, image/*
Браузер отправляет:
- User-Agent (какой браузер)
- Prefer-* заголовки (WebP, AVIF поддержка)
- Referer (откуда запрос)
3. Сервер обрабатывает запрос
Сервер:
- Проверяет файл существует
- Возвращает статус 200 OK
- Отправляет картинку с заголовками:
HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Length: 245000
Cache-Control: max-age=31536000
ETag: "abc123"
4. Загрузка данных
Данные загружаются в chunks (куски):
Шаг 1: Браузер → Server: GET запрос
Шаг 2: Server → Браузер: 200 OK заголовки (быстро)
Шаг 3: Server → Браузер: Данные в куски
[chunk1] [chunk2] [chunk3] ... [chunkN]
~50KB ~50KB ~50KB (всего 245KB)
Время загрузки зависит от:
- Размера файла (мегабайты? килобайты?)
- Скорости интернета (мобила? WiFi? 5G?)
- Сетевых задержек (latency)
- Сжатия на сервере (gzip, WebP)
5. Браузер декодирует изображение
После получения данных:
Браузер получил: JPEG бинарные данные
↓
Декодирование (JPEG декодер)
↓
Pixmap в памяти (RGB пиксели)
↓
Отправка в GPU (если поддерживается)
Декодирование занимает время!
Размер JPEG | Время декодирования
100KB | 5ms
1MB | 50ms
10MB | 500ms (заметно замедление!)
6. Расчёт размера на странице
Браузер вычисляет как изобразить картинку:
// Случай 1: явный размер
<img src="photo.jpg" width="800" height="600">
// Используются эти размеры
// Случай 2: размер из CSS
<img src="photo.jpg" style="width: 50%; height: auto;">
// width = 50% от контейнера
// height вычисляется с сохранением aspect ratio
// Случай 3: без размера (плохо!)
<img src="photo.jpg">
// Браузер ждёт загрузки чтобы узнать размер
// => Layout shift (испортит CLS метрику!)
7. Рендеринг на экран
Parsing → Layout → Paint → Composite
(измер) (рисуем) (на экран)
<img size=800x600>
↓
Layout: Выделить место 800x600
↓
Paint: Отрисовать пиксели
↓
Composite: Отправить на GPU
↓
Экран: Пользователь видит картинку
Оптимизация: как ускорить загрузку
1. Используй разные форматы
<!-- Браузер загрузит первый поддерживаемый формат -->
<picture>
<!-- Самый компактный, но не все браузеры поддерживают -->
<source srcset="photo.avif" type="image/avif">
<!-- WebP меньше чем JPEG на 30% -->
<source srcset="photo.webp" type="image/webp">
<!-- Fallback для старых браузеров -->
<img src="photo.jpg" alt="Photo">
</picture>
2. Адаптивные картинки (для разных размеров экрана)
<!-- Мобила получит маленькую картинку, десктоп - большую -->
<img
srcset="photo-400w.jpg 400w,
photo-800w.jpg 800w,
photo-1200w.jpg 1200w"
src="photo-800w.jpg"
alt="Photo"
>
3. Ленивая загрузка (lazy loading)
<!-- Картинка загружается только когда видна пользователю -->
<img src="photo.jpg" loading="lazy">
Как работает:
Пользователь: Загрузил страницу
↓
Браузер: Видны картинки? Загружаю.
Невидны картинки? Пропускаю.
↓
Пользователь: Скроллит вниз
↓
Браузер: Картинка стала видна? Загружаю сейчас!
4. Предварительная загрузка (preload)
<head>
<!-- Загружается в фоне, высокий приоритет -->
<link rel="preload" as="image" href="hero.jpg">
</head>
5. Сжатие на сервере
# Оригинал: 2MB
# После WebP конвертации: 500KB (4x меньше!)
convert original.jpg -quality 85 compressed.webp
# Проверь размер
ls -lh compressed.webp
# 500K compressed.webp
Параллельная загрузка
Браузер может загружать несколько картинок одновременно:
<img src="1.jpg">
<img src="2.jpg"> Загружаются ПАРАЛЛЕЛЬНО
<img src="3.jpg"> (не по очереди)
<img src="4.jpg">
Время: 0ms 500ms 1000ms
[==1==] [==2==] [==3==] Последовательно (плохо)
[==1.jpg==]
[==2.jpg==] Параллельно (хорошо - браузер умный)
[==3.jpg==]
[==4.jpg==]
~1500ms vs ~600ms
Процесс в деталях (Network tab)
Chrome DevTools → Network tab
1. Queued: 50ms - ждёт в очереди загрузок
2. DNS lookup: 100ms - резолвим IP сервера
3. Initial connection: 150ms - подключаемся к серверу
4. SSL/TLS: 200ms - устанавливаем HTTPS
5. Request sent: 10ms - отправляем GET
6. Waiting (TTFB): 300ms - ждём первого байта
7. Content Download: 400ms - загружаем данные
Всего: ~1210ms
Проблемы и как избежать
Проблема 1: Очень большие картинки
// Плохо: 5MB JPEG
<img src="huge-photo-5mb.jpg">
// Загрузка: 10+ секунд на мобиле
// Хорошо: оптимизировано
<picture>
<source srcset="photo-optimal.webp" type="image/webp">
<img src="photo-optimal.jpg" alt="photo"> <!-- 200KB -->
</picture>
Проблема 2: Layout shift
<!-- Плохо: высота неизвестна, сдвигается при загрузке -->
<img src="photo.jpg">
<!-- Хорошо: высота известна, нет сдвига -->
<img src="photo.jpg" width="800" height="600" alt="Photo">
Проблема 3: Много HTTP запросов
<!-- Плохо: 100 картинок = 100 запросов -->
<img src="1.jpg">
<img src="2.jpg">
...
<img src="100.jpg">
<!-- Хорошо: спрайт или SVG -->
<svg>...</svg>
Инструменты для анализа
# Chrome DevTools
# 1. Network tab - время загрузки
# 2. Performance tab - когда рисуется
# 3. Lighthouse - рекомендации
#命令 строка
wget --spider http://example.com/image.jpg # размер
file image.jpg # формат
identify image.jpg # размеры в пиксели
Резюме процесса
1. HTML парсинг → нашёл <img src="...">
2. HTTP GET запрос → Server
3. Server отправляет данные chunks
4. Браузер декодирует (JPEG/PNG/WebP)
5. Вычисляет размер на странице
6. Рендерит в Layout
7. Paint пиксели
8. Отправляет на GPU
9. Пользователь видит картинку!
Время: 100ms - 5000ms (зависит от оптимизации)
Чеклист оптимизации
[ ] Используй WebP/AVIF форматы
[ ] Сожми картинки (TinyPNG, ImageOptim)
[ ] Добавь width/height для избежания layout shift
[ ] Используй loading="lazy" для невидимых картинок
[ ] Используй <picture> для разных форматов
[ ] Используй srcset для разных размеров экрана
[ ] Используй CDN для быстрой доставки
[ ] Кешируй с Cache-Control заголовками