Один заголовок в HTTP-запросе способен сократить объём скачиваемых данных в несколько раз. Речь идёт о согласовании сжатия между клиентом и сервером. Если вы работаете с прокси и платите за каждый гигабайт трафика, эта тема напрямую влияет на ваш счёт. В этом гайде мы разберём, как заставить сервер отдавать сжатый ответ, как измерить реальную экономию на своей задаче и какие подводные камни вас ждут.

Введение: один заголовок способен урезать трафик в несколько раз

HTTP-сжатие работает на удивление просто. Клиент сообщает серверу, какие алгоритмы сжатия он понимает. Сервер выбирает подходящий, сжимает тело ответа и отправляет его. Клиент распаковывает данные на своей стороне. В результате по сети передаётся не исходный HTML или JSON, а его сжатая версия, которая часто весит в три-пять раз меньше.

Что вы получите в итоге. После прочтения этого гайда вы будете уметь включать сжатие на стороне клиента, проверять, действительно ли сервер отдаёт сжатый ответ, измерять экономию трафика в байтах до и после, а также диагностировать ситуации, когда сжатие по каким-то причинам не работает. Всё это критично, когда вы гоняете трафик через прокси Proxeon и платите за гигабайты.

Для кого этот гайд. Материал рассчитан на разработчиков, специалистов по парсингу, инженеров автоматизации и всех, кто пишет клиенты для работы с HTTP через прокси. Уровень средний. Мы не будем разбирать, из чего вообще складывается расход трафика в целом. Этому посвящена отдельная статья. Здесь мы сфокусируемся строго на сжатии.

Что нужно знать заранее. Достаточно базового понимания того, что такое HTTP-запрос и ответ, что такое заголовки и как запустить команду в терминале. Если вы хоть раз делали запрос через curl или писали скрипт на Python либо Node.js, вы справитесь без труда.

Сколько времени потребуется. На чтение и повторение всех примеров уйдёт около шестидесяти минут. Первые практические результаты вы увидите уже через десять минут, когда сравните размер сжатого и несжатого ответа своими глазами.

Предварительная подготовка

Перед тем как начать, убедитесь, что у вас есть всё необходимое. Это сэкономит время и избавит от ошибок на середине пути.

Необходимые инструменты

  • curl версии 7.72 или новее. В сборках 2026 года brotli и zstd поддерживаются из коробки на большинстве систем.
  • Python версии 3.10 или новее с установленной библиотекой requests, а для brotli дополнительно пакет brotli или brotlicffi.
  • Node.js версии 18 или новее. Модуль zlib встроен и умеет gzip, deflate, brotli.
  • Доступ к прокси Proxeon, если вы хотите измерять экономию именно в тех условиях, в которых работаете каждый день.
  • Любой текстовый редактор для написания скриптов.

Системные требования

Подойдёт любая современная система: Windows, macOS или Linux. Все примеры кроссплатформенные. Оперативной памяти хватит и двух гигабайт. Никаких особых требований к процессору нет, хотя при сжатии больших объёмов алгоритм brotli на максимальном уровне может заметно грузить одно ядро.

Что установить и проверить

  1. Откройте терминал и выполните команду проверки версии curl:
    curl --version
  2. Посмотрите на первую строку вывода. Там указана версия. Убедитесь, что в списке возможностей присутствуют brotli и по возможности zstd.
  3. Проверьте Python командой
    python --version
    и установите зависимости:
    pip install requests brotli
  4. Проверьте Node.js командой
    node --version

Совет: Если curl в вашей системе собран без brotli, установите его через официальный пакетный менеджер вашей ОС. В корпоративных сборках 2026 года brotli почти всегда включён по умолчанию.

Резервные копии. В этом гайде мы не меняем конфигурацию рабочих серверов и не трогаем боевые данные. Мы только отправляем запросы и измеряем ответы. Поэтому резервные копии не требуются. Однако если позже вы решите включать сжатие на своём собственном веб-сервере, обязательно сохраните исходный конфигурационный файл перед правкой.

✅ Проверка: Все три инструмента отвечают на команду проверки версии и показывают номер. Значит, подготовка завершена, можно двигаться дальше.

Базовые понятия простым языком

Прежде чем нажимать кнопки, разберёмся в терминах. Это займёт пять минут, но избавит от путаницы в дальнейшем.

Как работает согласование сжатия

HTTP-сжатие держится на трёх заголовках. Понимание их роли решает большинство проблем.

Accept-Encoding у клиента. Это заголовок, который отправляет ваш клиент вместе с запросом. В нём перечислены алгоритмы сжатия, которые клиент умеет распаковывать. Например, строка

Accept-Encoding: gzip, br, zstd
говорит серверу: я пойму gzip, brotli или zstd, выбирай любой из них. Если этого заголовка нет, сервер считает, что клиент хочет несжатый ответ.

Content-Encoding в ответе. Это заголовок, который добавляет сервер в свой ответ. Он сообщает, каким именно алгоритмом сжато тело. Если вы видите

Content-Encoding: br
, значит тело сжато алгоритмом brotli, и клиенту нужно его распаковать. Если этого заголовка в ответе нет, тело пришло в исходном виде.

Vary на стороне сервера. Заголовок Vary говорит кэшам и прокси, что ответ зависит от определённых заголовков запроса. Для сжатия критично значение

Vary: Accept-Encoding
. Оно означает, что для клиента с gzip и для клиента без сжатия должны храниться разные версии в кэше. Без этого заголовка кэш может отдать сжатый ответ клиенту, который не умеет его распаковывать, и наоборот.

Ключевая идея согласования

Запомните последовательность. Клиент просит через Accept-Encoding. Сервер решает и отвечает через Content-Encoding. Промежуточные звенья ориентируются на Vary. Если хотя бы одно звено этой цепочки сломано, вы получите несжатый ответ и переплатите за трафик.

Совет: Даже если ваша HTTP-библиотека добавляет Accept-Encoding автоматически, всегда проверяйте фактический заголовок ответа. Автоматика иногда молчит, а трафик уходит.

gzip, deflate, brotli, zstd: сравнение алгоритмов

Существует четыре распространённых алгоритма сжатия для HTTP. Они различаются степенью сжатия и нагрузкой на процессор. Разберём каждый и сведём цифры в таблицу.

gzip

Самый старый и универсальный. Поддерживается абсолютно везде: любой сервер, любой клиент, любой прокси. Даёт хорошую степень сжатия на текстовых данных при умеренной нагрузке. Если сомневаетесь, что выбрать, начинайте с gzip.

deflate

Близкий родственник gzip, использует тот же алгоритм внутри, но с другой обёрткой. На практике встречается реже и иногда реализован с ошибками на серверах. Степень сжатия примерно как у gzip. Особых причин выбирать deflate вместо gzip нет.

brotli

Современный алгоритм, разработанный специально для веба. На текстовых данных сжимает заметно сильнее gzip, особенно на HTML, CSS и JSON. Расплата за это выше нагрузка на процессор при сжатии на максимальных уровнях. Распаковка быстрая. Обозначается в заголовках как br.

zstd

Быстрый современный алгоритм с гибкой настройкой уровней. Даёт степень сжатия на уровне brotli, но при этом работает быстрее по скорости сжатия. Поддержка в вебе растёт, к 2026 году большинство актуальных серверов и клиентов его понимают. Обозначается как zstd.

Таблица сравнения на типичном текстовом ответе

Возьмём условный JSON-ответ размером 1000 килобайт в несжатом виде. Цифры ориентировочные, они зависят от содержимого, но порядок величин отражают верно.

  • Без сжатия: 1000 КБ, экономия 0 процентов, нагрузка на процессор минимальная.
  • gzip уровень 6: около 190 КБ, экономия примерно 81 процент, нагрузка низкая.
  • deflate уровень 6: около 195 КБ, экономия примерно 80 процентов, нагрузка низкая.
  • brotli уровень 5: около 165 КБ, экономия примерно 83 процента, нагрузка средняя.
  • brotli уровень 11: около 140 КБ, экономия примерно 86 процентов, нагрузка высокая.
  • zstd уровень 3: около 175 КБ, экономия примерно 82 процента, нагрузка низкая.
  • zstd уровень 19: около 150 КБ, экономия примерно 85 процентов, нагрузка средняя.

Вывод простой. На текстовых данных любое сжатие снижает трафик примерно в пять раз. Разница между алгоритмами в пределах нескольких процентов. Поэтому для экономии трафика через прокси главное не какой алгоритм, а сам факт того, что сжатие включено.

Совет: Если вы только скачиваете данные, а не отдаёте, нагрузка на ваш процессор идёт только на распаковку, а она у всех алгоритмов быстрая. Значит, вы можете смело просить самый выгодный по степени сжатия вариант.

✅ Проверка: Вы понимаете, что brotli и zstd обычно чуть эффективнее gzip на тексте, но gzip самый совместимый. Этого достаточно для практики.

Шаг 1: Отправляем запрос и смотрим, сжимается ли ответ

Цель этапа. Научиться видеть заголовки Content-Encoding и реальный размер тела. Без этого невозможно измерить экономию.

Проверка через curl

  1. Откройте терминал.
  2. Сначала запросите ресурс без сжатия, чтобы узнать исходный размер. Выполните:
    curl -s -o /dev/null -w "%{size_download}" https://example.com/api/data
  3. Запишите число. Это размер несжатого ответа в байтах.
  4. Теперь попросите сжатие. Флаг --compressed автоматически добавляет Accept-Encoding и распаковывает ответ:
    curl -s --compressed -o /dev/null -w "%{size_download}" https://example.com/api/data
  5. Сравните два числа. Второе должно быть заметно меньше при том же содержимом.

Важно: Показатель size_download в curl при использовании --compressed отражает размер уже распакованных данных, а не то, сколько прошло по сети. Чтобы увидеть реальный сетевой объём, используйте заголовок ответа и промежуточные замеры, о которых мы поговорим в шаге измерения.

Смотрим заголовки ответа

  1. Выполните запрос с флагом вывода заголовков:
    curl -s -I --compressed https://example.com/api/data
  2. Найдите в выводе строку Content-Encoding. Если там gzip, br или zstd, сервер отдал сжатый ответ.
  3. Найдите строку Vary. Наличие Accept-Encoding в ней означает корректную настройку кэширования.

Совет: Чтобы явно указать нужный алгоритм, добавьте заголовок вручную:

curl -s -H "Accept-Encoding: br" -I https://example.com/api/data
Так вы проверите, умеет ли сервер именно brotli.

Работа через прокси Proxeon

Чтобы измерять экономию в реальных условиях, направьте запрос через прокси. В curl это делается флагом -x:

curl -s --compressed -x http://логин:пароль@адрес_proxeon:порт -o /dev/null -w "%{size_download}" https://example.com/api/data

Так вы увидите, доходит ли сжатие через прокси и не вырезает ли что-то заголовки по пути.

Ожидаемый результат. Вы видите два числа: размер без сжатия и размер со сжатием. И вы видите заголовок Content-Encoding в ответе. Это значит, что механизм работает.

Возможная проблема: если оба числа одинаковые и Content-Encoding отсутствует, сервер не отдал сжатие. Причины разберём в отдельном разделе.

✅ Проверка: В ответе с флагом --compressed присутствует строка Content-Encoding с одним из алгоритмов. Значит, шаг выполнен.

Шаг 2: Измеряем реальную экономию на Python

Цель этапа. Получить точные цифры сетевого трафика до и после сжатия рабочим скриптом, который можно применить к своей задаче.

Простой замер через requests

Библиотека requests по умолчанию сама добавляет Accept-Encoding и распаковывает ответ. Чтобы измерить именно сетевой размер, мы посмотрим на длину сырого содержимого до распаковки.

  1. Создайте файл measure.py.
  2. Вставьте следующий код:
import requests
url = "https://example.com/api/data"
# Запрос без сжатия
r_plain = requests.get(url, headers={"Accept-Encoding": "identity"})
size_plain = len(r_plain.content)
# Запрос со сжатием
r_comp = requests.get(url, headers={"Accept-Encoding": "gzip, br, zstd"})
encoding = r_comp.headers.get("Content-Encoding", "нет")
size_wire = int(r_comp.headers.get("Content-Length", 0))
size_body = len(r_comp.content)
print("Без сжатия, байт:", size_plain)
print("Алгоритм сжатия:", encoding)
print("По сети примерно, байт:", size_wire)
print("После распаковки, байт:", size_body)
if size_plain and size_wire:
saved = 100 - size_wire * 100 
print("Экономия трафика, процентов:", saved)

Внимание: Значение Content-Length не всегда присутствует, особенно при потоковой передаче chunked. Если оно отсутствует, используйте более точный способ ниже.

Точный замер сетевого объёма

Чтобы измерить именно то, что прошло по сети, отключите автоматическую распаковку и посчитайте байты сырого потока.

import requests
url = "https://example.com/api/data"
sess = requests.Session()
# Отключаем авто-распаковку, чтобы увидеть сырой размер
r = sess.get(url, headers={"Accept-Encoding": "gzip, br, zstd"}, stream=True)
raw_bytes = 0
for chunk in r.raw.stream(8192, decode_content=False):
raw_bytes += len(chunk)
print("Алгоритм:", r.headers.get("Content-Encoding", "нет"))
print("Сырых байт по сети:", raw_bytes)

Сравните raw_bytes с размером несжатого запроса. Разница и есть ваша реальная экономия.

Замер через прокси Proxeon

Добавьте параметр proxies, чтобы получить цифры в боевых условиях:

proxies = {
"http": "http://логин:пароль@адрес_proxeon:порт",
"https": "http://логин:пароль@адрес_proxeon:порт",
}
r = sess.get(url, headers={"Accept-Encoding": "gzip, br, zstd"}, proxies=proxies, stream=True)

Совет: Прогоните замер несколько раз и усредните. Динамические ответы меняются по размеру, поэтому одиночный замер может ввести в заблуждение.

Ожидаемый результат. Скрипт печатает алгоритм сжатия и число сырых байт, которое меньше размера несжатого ответа. Если экономия составила семьдесят и более процентов на текстовом ресурсе, всё работает как надо.

✅ Проверка: В выводе алгоритм не равен слову нет, а сырых байт меньше, чем без сжатия. Отлично.

Шаг 3: Тот же замер на Node.js

Цель этапа. Получить рабочий инструмент измерения на JavaScript для тех, кто пишет клиенты на Node.

Замер сырого потока

  1. Создайте файл measure.js.
  2. Вставьте код, который считает байты до распаковки:
const https = require('https');
const url = 'https://example.com/api/data';
function measure(acceptEncoding) {
 return new Promise((resolve) => {
const req = https.get(url, { headers: { 'Accept-Encoding': acceptEncoding } }, (res) => {
 let bytes = 0;
 res.on('data', (chunk) => { bytes += chunk.length; });
 res.on('end', () => {
resolve({ enc: res.headers['content-encoding'] || 'нет', bytes });
 });
});
req.end();
 });
}
(async () => {
 const plain = await measure('identity');
 const comp = await measure('gzip, br, zstd');
 console.log('Без сжатия, байт:', plain.bytes);
 console.log('Алгоритм:', comp.enc);
 console.log('Сжато по сети, байт:', comp.bytes);
 const saved = Math.round(100 - (comp.bytes * 100) / plain.bytes);
 console.log('Экономия, процентов:', saved);
})();

Важно: В этом примере мы читаем сырой поток из res и не подключаем zlib. Значит, счётчик bytes показывает именно сетевой объём. Это ровно то, за что вы платите провайдеру прокси.

Ручная распаковка на Node

Если вам нужно ещё и прочитать содержимое, распакуйте поток через встроенный модуль zlib:

const zlib = require('zlib');
let stream = res;
const enc = res.headers['content-encoding'];
if (enc === 'gzip') stream = res.pipe(zlib.createGunzip());
else if (enc === 'br') stream = res.pipe(zlib.createBrotliDecompress());
else if (enc === 'deflate') stream = res.pipe(zlib.createInflate());

Совет: Для zstd в свежих версиях Node.js есть zlib.createZstdDecompress. Если ваша версия его не содержит, обновите Node или используйте отдельный npm-пакет.

Ожидаемый результат. Node печатает экономию в процентах, сопоставимую с тем, что вы получили на Python и curl.

✅ Проверка: Три инструмента дают близкие цифры экономии. Значит, ваши измерения достоверны.

Шаг 4: Почему ответ приходит несжатым

Цель этапа. Научиться диагностировать, почему сжатие не сработало, и устранять причину. Это самая частая проблема на практике.

Случай первый: клиент не попросил

Самая распространённая причина. Ваш HTTP-клиент не отправил заголовок Accept-Encoding, и сервер честно отдал несжатый ответ. Так бывает, когда вы вручную формируете заголовки и забываете про сжатие, или когда используете низкоуровневый сокет.

  1. Проверьте, что именно уходит на сервер. В curl добавьте флаг -v и найдите строку с Accept-Encoding в исходящих заголовках.
  2. Если строки нет, добавьте её явно через -H или флаг --compressed.
  3. В Python убедитесь, что не переопределили заголовок пустым значением.

Внимание: Некоторые библиотеки при ручной установке любого заголовка перестают добавлять свои значения по умолчанию. Если вы задаёте User-Agent руками, проверьте, что Accept-Encoding не пропал заодно.

Случай второй: сервер не умеет

Сервер может не поддерживать сжатие вовсе, либо не поддерживать запрошенный алгоритм. Тогда он отдаёт несжатый ответ, что по стандарту допустимо.

  1. Попросите разные алгоритмы по очереди: сначала gzip, потом br, потом zstd.
  2. Смотрите, при каком из них появляется Content-Encoding в ответе.
  3. Если ни при каком, сервер сжатие не отдаёт. На чужом сервере вы это изменить не можете, но можете выбрать другой эндпоинт или API, если он есть.

Совет: Многие API отдают сжатие только для ответов больше определённого размера. Маленькие ответы сервер часто оставляет несжатыми специально, потому что накладные расходы на сжатие превышают выгоду.

Случай третий: посредник вырезал заголовок

Между вами и сервером может стоять кэширующий узел, шлюз или прокси, который удаляет или изменяет заголовки сжатия. Иногда посредник распаковывает ответ для своих нужд и отдаёт вам уже распакованный вариант.

  1. Сделайте запрос напрямую и через прокси и сравните заголовки Content-Encoding.
  2. Если напрямую сжатие есть, а через посредник его нет, значит посредник вмешивается.
  3. При работе через прокси Proxeon сжатие передаётся прозрачно, поэтому если вы видите разницу, ищите проблему на стороне целевого сервера или его CDN.

Ожидаемый результат. Вы точно знаете, на каком из трёх звеньев теряется сжатие, и понимаете, что с этим делать.

✅ Проверка: Вы можете объяснить одним предложением, почему конкретный ответ пришёл несжатым. Диагностика освоена.

Шаг 5: Подводные камни при работе со сжатием

Цель этапа. Избежать тонких ошибок, которые ломают данные или искажают замеры.

Двойное сжатие

Иногда контент уже сжат на уровне приложения, а сервер сжимает его ещё раз. Или наоборот: вы сжимаете тело запроса, а прокси или библиотека делают это повторно. Двойное сжатие почти не даёт выигрыша, а иногда даже увеличивает размер и точно тратит процессор впустую.

  1. Проверьте, нет ли в ответе сразу двух значений в Content-Encoding, например gzip внутри br.
  2. Не сжимайте вручную то, что библиотека уже сожмёт автоматически.
  3. Если видите цепочку кодировок, распаковывайте её в обратном порядке.

Повреждённый поток

Обрыв соединения или ошибка посредника может привести к тому, что сжатый поток придёт неполным. При распаковке вы получите ошибку или обрезанные данные.

  1. Всегда оборачивайте распаковку в обработку ошибок.
  2. При ошибке распаковки повторите запрос, а не пытайтесь читать битые данные.
  3. Сравнивайте фактический размер с Content-Length, если он указан.

Внимание: Никогда не сохраняйте частично распакованные данные как результат. Битый JSON выглядит правдоподобно, но приведёт к скрытым ошибкам дальше по конвейеру.

Ручная распаковка, когда библиотека этого не делает

Если вы отключили авто-распаковку ради точного замера или используете низкоуровневый клиент, распаковывать придётся вручную. Пример на Python:

import gzip, brotli, zlib
def decompress(data, encoding):
if encoding == "gzip":
return gzip.decompress(data)
if encoding == "br":
return brotli.decompress(data)
if encoding == "deflate":
return zlib.decompress(data)
return data

Совет: Если распаковка deflate падает с ошибкой, попробуйте вызвать zlib.decompress с параметром wbits равным минус пятнадцать. Некоторые серверы отдают чистый deflate без обёртки zlib.

Ожидаемый результат. Вы умеете распаковывать любой из поддерживаемых форматов вручную и корректно обрабатываете ошибки потока.

✅ Проверка: Ваш скрипт не падает на битом ответе, а повторяет запрос. Устойчивость достигнута.

Шаг 6: Что сжимать бессмысленно

Цель этапа. Не тратить процессор и время на сжатие того, что уже сжато. Это экономит ресурсы без потери выгоды по трафику.

Уже сжатые форматы

Некоторые данные хранятся в форматах, которые внутри уже используют сжатие. Пытаться сжать их повторно бессмысленно: выигрыш составит доли процента, а процессор загрузится зря.

  • Изображения: JPEG, PNG, WebP, AVIF уже сжаты внутри своего формата.
  • Видео: MP4, WebM, MKV содержат сильно сжатый видеопоток.
  • Аудио: MP3, AAC, OGG сжаты по своей природе.
  • Архивы: ZIP, RAR, 7z, gz уже представляют собой сжатые контейнеры.

Для таких ресурсов Accept-Encoding не даст экономии по телу. Более того, сервер обычно и сам не сжимает их повторно, потому что настроен по списку MIME-типов.

Что сжимать имеет смысл

  • HTML, CSS, JavaScript.
  • JSON и XML ответы API.
  • Обычный текст, CSV, логи.
  • SVG, потому что это по сути текст.

Совет: Если вы качаете преимущественно медиафайлы, экономия от сжатия будет околонулевой. Тут выигрыш даёт другое: запрашивать только нужные размеры и форматы, а не сам факт сжатия. Но это уже тема управления трафиком, а не сжатия как такового.

Ожидаемый результат. Вы не тратите ресурсы на сжатие бинарных форматов и применяете сжатие только там, где оно реально помогает.

✅ Проверка: Вы можете за секунду сказать, стоит ли сжимать конкретный тип ответа. Понимание сформировано.

Проверка результата

Пришло время убедиться, что вы всё настроили правильно. Пройдите по чек-листу.

Чек-лист работоспособности

  1. Ваш клиент отправляет заголовок Accept-Encoding с нужными алгоритмами.
  2. В ответе присутствует Content-Encoding с одним из этих алгоритмов на текстовых ресурсах.
  3. Скрипт замера показывает сетевой объём меньше несжатого хотя бы на семьдесят процентов для текста.
  4. Через прокси Proxeon сжатие сохраняется, цифры совпадают с прямым запросом.
  5. Распаковка не выдаёт ошибок, а данные читаются корректно.
  6. Бинарные форматы вы не пытаетесь сжимать.

Как протестировать

  1. Возьмите три разных эндпоинта: один с JSON, один с HTML, один с изображением.
  2. Прогоните каждый через ваш скрипт замера.
  3. Убедитесь, что на первых двух экономия высокая, а на третьем близка к нулю.

Показатели успеха. Для текстового API вы стабильно видите экономию в диапазоне от семидесяти до девяноста процентов. Для медиа экономия минимальна, и это нормально. Через прокси цифры не ухудшаются.

✅ Проверка: Все шесть пунктов чек-листа выполнены. Сжатие настроено и измерено верно.

Типичные ошибки и решения

Ниже собраны частые проблемы в формате проблема, причина, решение.

Ответ не сжимается, хотя Accept-Encoding отправлен

Причина: сервер не поддерживает сжатие для этого типа контента или для ответов такого размера. Решение: попробуйте другой алгоритм и убедитесь, что ресурс текстовый и достаточно крупный.

Экономия по curl не видна, size_download не меняется

Причина: флаг --compressed показывает размер после распаковки. Решение: измеряйте сетевой объём отдельным скриптом без авто-распаковки, как в шагах на Python и Node.

Библиотека выдаёт мусор вместо текста

Причина: вы отключили авто-распаковку, но не распаковали поток вручную. Решение: определите Content-Encoding и примените соответствующую функцию распаковки.

Ошибка при распаковке deflate

Причина: сервер отдал сырой deflate без обёртки. Решение: вызовите распаковку с параметром wbits минус пятнадцать.

Через прокси сжатие пропадает

Причина: на пути стоит узел, изменяющий заголовки, чаще всего это CDN целевого сайта. Решение: сравните прямой и проксированный запрос и определите звено. Прокси Proxeon передаёт заголовки прозрачно, поэтому проблема обычно на стороне сервера.

Разный размер ответа при повторных замерах

Причина: контент динамический и меняется от запроса к запросу. Решение: усредняйте несколько замеров и сравнивайте на одинаковых параметрах запроса.

Content-Length отсутствует

Причина: потоковая передача chunked не указывает длину заранее. Решение: считайте байты вручную по мере чтения потока, как в примерах скриптов.

Двойное сжатие раздувает процессор

Причина: контент сжимается дважды на разных уровнях. Решение: уберите ручное сжатие там, где его делает библиотека или сервер.

Дополнительные возможности

Когда базовый сценарий освоен, есть куда развиваться.

Выбор приоритета алгоритмов

В заголовке Accept-Encoding можно указывать вес через q-значения, подсказывая серверу предпочтения. Например

Accept-Encoding: zstd;q=1.0, br;q=0.9, gzip;q=0.8
просит по возможности zstd, затем brotli, затем gzip. Не все серверы учитывают веса, но многие уважают порядок.

Кэширование распакованных данных

Если вы многократно обращаетесь к одному ресурсу, кэшируйте распакованный результат на своей стороне. Это снижает и трафик, и нагрузку на процессор от повторной распаковки.

Массовое измерение по списку URL

Оберните скрипт замера в цикл по списку эндпоинтов и соберите таблицу экономии. Так вы найдёте самые тяжёлые несжатые ответы в вашем проекте и в первую очередь займётесь ими.

Совет: Ведите журнал экономии в байтах за сутки. Умножив на цену гигабайта, вы получите наглядную денежную выгоду от включённого сжатия при работе через прокси.

✅ Проверка: Вы можете собрать сводную таблицу экономии по нескольким ресурсам одним запуском скрипта.

FAQ

Нужно ли всегда просить brotli вместо gzip?

Если вы только скачиваете, распаковка у всех алгоритмов быстрая, поэтому можно просить самый эффективный. На практике укажите в Accept-Encoding все три: gzip, br, zstd. Сервер выберет лучший из доступных.

Сколько трафика экономит сжатие на текстовом API?

Обычно от семидесяти до девяноста процентов. То есть ответ, который весил гигабайт, по сети пройдёт как сто пятьдесят или двести мегабайт. Экономия при оплате за гигабайты прямая и заметная.

Влияет ли сжатие на скорость ответа?

Меньший объём данных передаётся быстрее, особенно на медленных каналах. Небольшая задержка на сжатие у сервера обычно с лихвой окупается сокращением времени передачи.

Почему curl показывает одинаковый размер с флагом сжатия и без?

Потому что --compressed выводит размер уже распакованного тела. Реальный сетевой объём меньше. Измеряйте сырой поток отдельным скриптом.

Можно ли сжимать тело POST-запроса?

Да, для этого клиент ставит Content-Encoding в запросе, но сервер должен уметь его распаковывать. Не все серверы это поддерживают, поэтому проверяйте документацию API.

Сжатие работает через прокси Proxeon?

Да. Прокси передаёт заголовки Accept-Encoding и Content-Encoding прозрачно, поэтому вся экономия сохраняется. Именно поэтому измерять выгодно сразу через прокси, в боевых условиях.

Что делать, если сервер не отдаёт сжатие?

Убедитесь, что вы просите сжатие и что ресурс текстовый. Если сервер всё равно молчит, вы не можете изменить чужой сервер, но можете выбрать другой эндпоинт или сжать данные на своём кэширующем слое.

Стоит ли сжимать изображения через Accept-Encoding?

Нет. Форматы вроде JPEG и WebP уже сжаты. Дополнительное сжатие не даст выигрыша и только нагрузит процессор.

Как выбрать между zstd и brotli?

Для скачивания разница по трафику в пределах нескольких процентов. Указывайте оба в Accept-Encoding и позвольте серверу решить. Если сервер поддерживает только один, вы получите именно его.

Нужен ли Vary при клиентской работе?

Как клиент вы Vary не устанавливаете, его ставит сервер. Но понимать его полезно: он объясняет, почему кэш иногда отдаёт то сжатый, то несжатый вариант.

Заключение

Вы прошли путь от теории до рабочих измерений. Теперь вы понимаете, как согласуется сжатие через Accept-Encoding, Content-Encoding и Vary. Вы умеете просить сжатие в curl, Python и Node.js, а главное измерять реальный сетевой объём до и после. Вы знаете, почему ответ иногда приходит несжатым и как это диагностировать по трём типовым причинам. Вы разобрались с подводными камнями: двойным сжатием, битым потоком и ручной распаковкой. И вы больше не тратите ресурсы на сжатие изображений, видео и архивов.

Что делать дальше. Прогоните скрипт замера по всем основным эндпоинтам своего проекта. Найдите те, где сжатие не включено, и попросите его явно. Ведите журнал сэкономленных байт, чтобы видеть денежную выгоду при работе через прокси Proxeon. Когда освоите базовый сценарий, переходите к массовому измерению по списку URL и приоритетам алгоритмов через q-значения.

Сжатие это один из самых дешёвых способов сократить счёт за трафик. Один правильно отправленный заголовок способен урезать объём данных в несколько раз. Теперь этот инструмент в ваших руках, и вы можете применять его осознанно и с точными цифрами на руках.