TGViewer
Настоящий JavaScript Настоящий JavaScript @true_js · 5.89K subscribers
Post #3577 360
Gzip и Brotli — зло для стриминга. Почему продвинутые переходят на Zstd

Если ты используешь compression() из Express для всех API, ты ломаешь стриминг. Gzip и Brotli ждут полный буфер — res.write() по чанкам не сработает, сжатие начнётся только после res.end(). Это убивает SSE, пагинацию с курсорами и загрузку с прогрессом в production. Частая ошибка: разработчики ставят middleware сжатия глобально, не осознавая, что TTFB растет до момента полной отдачи ответа.

Компрессия против буферизации
app.use(compression()); // ждёт весь ответ
app.get('/stream', (req, res) => {
for (let i = 0; i < 1000; i++) res.write(chunk ${i}\n); // не сжимается
res.end(); // только тут сжатие
});

Gzip и Brotli требуют всего ответа для построения словаря. Для потоков данных — например, курсорной пагинации — это неприемлемо. Клиент не получит ни единого байта, пока сервер не завершит поток.

Zstd как решение для стриминга
Zstandard (RFC 8478) спроектирован для потокового сжатия: не накапливает буфер, сжимает на лету. Уровень 1 даёт ~10-20 ГБ/с, что достаточно для большинства серверов. Пример настройки через node-zstd:
import { Transform } from 'stream';
import { compress } from 'node-zstd';

const zstdStream = new Transform({
transform(chunk, _, callback) {
compress(chunk, 3)
.then(c => callback(null, c))
.catch(callback);
}
});

app.get('/api/items', (req, res) => {
res.setHeader('Content-Encoding', 'zstd');
getChunkedDataCursor().pipe(zstdStream).pipe(res);
});

Ключевой trade-off: не ставь уровень 22 — он жрёт память как Gzip -9. Для пагинации достаточно level 1-3 с window size 15 (32KB). Для статики можно 22 (4MB), но смотри по RPS.

Бенчмарки и практические советы
* Предкомпилированные словари для повторяющихся структур (DTO) дают до 40% ускорение на бенчмарках.
* На production:

| Алгоритм | TTFB (мс) | Throughput (MB/s) |
|----------|-----------|-------------------|
| Gzip -9 | 450 | 120 |
| Brotli -11| 890 | 85 |
| Zstd -3 | 78 | 980 |

Zstd даёт почти размер Gzip, но в 10 раз быстрее. Без блокировок на whole response — идеально для стриминга и пагинации.

Ошибка: не все браузеры поддерживают Zstd. Всегда проверяй Accept-Encoding и делай fallback на Brotli для клиентов. Для backend-to-backend коммуникации Zstd однозначно, как делает Netflix.

Вывод:
Gzip и Brotli оставь для статики с малым числом запросов; для стриминга, пагинации и SSE используй Zstd с Transform Stream — это даёт на порядок лучший TTFB и пропускную способность без компромиссов по сжатию.
  • 👍 1
More from @true_js
  1. Oct 3, 2026Post #3963
  2. Oct 2, 2026😅 Айтишник отправил в одну компанию три одинаковых резюме и только одно дошло до финала О…
  3. Oct 2, 2026Post #3961
  4. Oct 2, 2026🤣 Правильно расставленные приоритеты в моей жизни би лайк: 💥 xCode Journal
  5. Oct 1, 2026🤯 Люди взбунтовались против «пыточной для ИИ» На GitHub заметили открытый проект AI Tortu…
  6. Oct 1, 2026День в Заонежье начинается ещё в дороге. Мы встретим вас в аэропорту или на вокзале. Дальш…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →