← Назад к вопросам

Как картинки загружаются на страницу?

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">

Браузер:

  1. Парсит HTML
  2. Видит <img src="...">
  3. Извлекает URL из атрибута src
  4. Создаёт объект 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. Сервер обрабатывает запрос

Сервер:

  1. Проверяет файл существует
  2. Возвращает статус 200 OK
  3. Отправляет картинку с заголовками:
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 заголовками