Top.Mail.Ru
OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

Новые горизонты после HTTP/2 Push: Link preload, приоритизация и кэш

HTTP/2 Server Push признан неудачным и исчезает из браузеров и HTTP/3. Разбираем, чем его заменить на практике: Link preload, приоритизация (Priority и fetchpriority), 103 Early Hints, а также сильный кэш с immutable и версионированием по хэшу. Пошаговый план, примеры и типичные ошибки.
Новые горизонты после HTTP/2 Push: Link preload, приоритизация и кэш

HTTP/2 Server Push задумывался как «магия», которая ускорит первый визит: сервер предугадывает, какие ресурсы понадобятся, и отправляет их до запроса. По факту идея оказалась сложной в эксплуатации и непредсказуемой для кэша. Поддержка постепенно вымывается: в браузерах фича отключена или нестабильна, в HTTP/3 от неё отказались. Что теперь делать админам, девопсам и веб-мастерам, которым важна производительность? Ответ: перейти на связку декларативных подсказок (preload), современной приоритизации и грамотного кэширования.

Коротко: что случилось с HTTP/2 Push

Причины отказа — практические. Push порождал дубликаты трафика при попадании в существующий кэш браузера, плохо вписывался в реальные цепочки прокси и CDN, усложнял дебаг и часто не давал прогнозируемого выигрыша в метриках. В HTTP/3 концепцию убрали, а индустрия сместилась в сторону декларативных подсказок клиенту и нового протокольного механизма приоритизации.

Итог: вместо «угадывания» на стороне сервера — явное объявление критических ресурсов, корректные приоритеты и сильный кэш, который делает повторные визиты мгновенными.

Почему Push не взлетел: уроки

  • Кэш-коллизии: если ресурс уже в кэше, серверный Push зря расходует канал.
  • Хрупкость цепочки: TLS-терминация, прокси и CDN по-разному обращаются с Push, часть данных просто не доходила.
  • Непрозрачность: waterfall в браузере неочевиден, отладка сложнее, регрессии — реальны.
  • Трудозатраты: поддержка конфигурации Push в релизном цикле стоила дороже, чем альтернативы.
  • Неуниверсальность: Push не знал контекста клиента (кэш, DPR, предпочтения, вариации по Vary), что приводило к неэффективным отправкам.

Новая тройка: preload, приоритизация и кэш

Сейчас ставка делается на:

  • Link preload — явное объявление критически важных ресурсов до парсинга HTML.
  • Приоритизация — протокольная (RFC 9218, заголовок Priority) и клиентские подсказки (fetchpriority) для выверенного порядка загрузки.
  • Кэш — агрессивное и предсказуемое кеширование статики (Cache-Control, immutable, SWR), плюс версионирование по хэшу.

Фрагмент конфигурации Nginx: Cache-Control и Priority для статики

Link rel="preload": когда он действительно нужен

Preload полезен для ресурсов, которые:

  • критичны для рендера первого экрана (Critical CSS, главный JS-бандл, LCP-изображение);
  • нужны раньше, чем браузер успеет их обнаружить при парсинге HTML;
  • загружаются из того же источника (меньше латентности и риска CORS-ошибок).

Рекомендации:

  • Всегда указывайте корректный as (например, as=style, as=script, as=font, as=image). Браузер опирается на это для приоритета и политики безопасности.
  • Для шрифтов добавляйте crossorigin и используйте font-display в CSS (часто swap), чтобы не блокировать текст.
  • Не перегружайте страницу десятками preload — это выродится в конкуренцию за канал. Выбирайте 2–5 действительно критичных ресурсов.
  • Держите декларации в одном месте: либо в HTML-голове, либо присылайте заголовком ответа Link. Дублирование мешает поддержке.
Link: </assets/app.css>; rel=preload; as=style
Link: </assets/runtime.js>; rel=preload; as=script
Link: </assets/lcp-hero.jpg>; rel=preload; as=image; imagesrcset="/assets/lcp-hero@2x.jpg 2x"

HTML-эквивалент:

<link rel="preload" href="/assets/app.css" as="style">
<link rel="preload" href="/assets/runtime.js" as="script">
<link rel="preload" href="/assets/lcp-hero.jpg" as="image" imagesrcset="/assets/lcp-hero@2x.jpg 2x">

103 Early Hints: полезно, когда бэкенд тяжёлый

Early Hints (статус 103) позволяют отдать заголовки Link: rel=preload ещё до финального ответа 200/302/… Это особенно помогает при высоком TTFB (дорогие запросы к БД, холодный кеш приложения). Браузер начинает качать критичные ассеты параллельно, и к моменту отрисовки они уже в полёте или закешированы.

Нюансы внедрения:

  • Проверьте, как ваша цепочка (балансировщик, прокси, CDN, веб-сервер, фреймворк) относится к промежуточным статусам. Часть компонентов далёко не всегда корректно форвардит 103.
  • Отлаживайте в DevTools: ищите блок «Early Hints» и убедитесь, что preload реально стартовал до ответа.
  • Не превращайте 103 в «мини-CDN-конфиг»: публикуйте только действительно критичные ресурсы.

На собственном VDS проще включить и контролировать 103, приоритизацию и заголовки кеширования централизованно. Для TLS-терминации используйте корректные SSL-сертификаты, чтобы не упираться в рукопожатия.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Приоритизация: Priority header и fetchpriority

Историческая приоритизация потоков в HTTP/2 была несовершенной; индустрия перешла к схеме RFC 9218 с заголовком Priority. Идея: клиент и сервер согласуют «срочность» (urgency) и инкрементальную доставку. Дополнительно в HTML появился атрибут fetchpriority для явного приоритета отдельных ресурсов.

Практика:

  • LCP-изображение: fetchpriority="high" в HTML и, при возможности, ответ сервера с Priority (высокая срочность).
  • Нефолдовые изображения и ассеты аналитики: низкий приоритет (fetchpriority="low" или низкая срочность в Priority), плюс кеширование.
  • CSS — всегда высокий приоритет, JS — в зависимости от роли (инициализация рендера vs. виджеты ниже фолда).
<img src="/assets/hero.jpg" width="1200" height="630" fetchpriority="high" alt="...">
<img src="/assets/gallery-3.jpg" loading="lazy" fetchpriority="low" alt="...">

Серверный заголовок (пример для статики с высокой срочностью):

Priority: u=0, i

Где u — срочность (0 — выше, 7 — ниже), i — инкрементальная доставка. Браузеры постепенно расширяют поддержку этой схемы и используют её и в HTTP/2, и в HTTP/3.

Resource Hints: preconnect и dns-prefetch

Если часть критичных ресурсов уходит на внешние источники, сокращайте сетевую латентность заранее:

  • preconnect — установка TCP/TLS ещё до первого запроса к домену.
  • dns-prefetch — только резолв DNS (менее затратный, но и менее полезный).
<link rel="preconnect" href="//cdn.example" crossorigin>
<link rel="dns-prefetch" href="//cdn.example">

Не перегибайте: избыточный preconnect может зря открыть слишком много соединений.

Кэш как главный ускоритель

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

  • Долгий TTL + immutable для версионированной статики (имена с хэшем: app.3f1a9d.css).
  • Стратегия ревалидции для динамики: ETag, Last-Modified, stale-while-revalidate, stale-if-error.
  • Правильный Vary (Accept-Encoding, DPR и т. п.), чтобы кэш не смешивал несовместимые варианты.
  • Brotli для текстовых форматов и условное кеширование HTML на прокси, если это безопасно для персонализации.
# Пример локации Nginx для статики с долгим TTL и immutable
location ~* \.(css|js|mjs|woff2|jpg|jpeg|png|webp|avif|svg)$ {
    expires 1y;
    add_header Cache-Control "public, max-age=31536000, immutable";
}

Важно: если не используете имена с хэшем, нельзя ставить большой TTL и immutable — клиенты не увидят обновления. Подробно про практики см. разделы версионирование по хэшу для S3/CDN и Cache-Control и ETag на практике.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

План миграции с HTTP/2 Push

  1. Отключите Push в конфигурации веб-сервера/CDN. Уберите устаревшие директивы и плагины, чтобы не было «тихих» отправок.
  2. Постройте критический путь рендера: какие ресурсы нужны для первого экрана? Смотрите на LCP и FCP.
  3. Добавьте preload для выбранных 2–5 ресурсов. Проверьте, что as и crossorigin корректны, а сами ресурсы доступны.
  4. Настройте приоритеты: используйте fetchpriority в разметке, а на сервере — заголовок Priority там, где это оправдано.
  5. Включите сильный кэш: версионирование по хэшу, долгий TTL, immutable. Для HTML — консервативные значения и ревалидация.
  6. Экспериментируйте с 103 Early Hints, если TTFB высок. Следите, чтобы промежуточная инфраструктура не «съедала» 103.
  7. Промерьте эффект по LCP/FCP/TTFB, сравните waterfall, проверьте отсутствие дубликатов запросов и регрессий.

Частые ошибки и как их избежать

  • Preload без as. Браузер теряет контекст и может понизить приоритет или запросить ресурс повторно.
  • Шрифт без crossorigin. Получите двойные запросы или CORS-ошибки.
  • Избыточный preload всего подряд. Итог — перегруженный конвейер, рост TTFB для HTML и ухудшение LCP.
  • Несогласованность кэша: большой TTL без версионирования. Пользователи не видят обновления.
  • Дублирование Link-заголовков и тэгов в HTML. Содержите объявление ресурсов в одном месте.
  • Преждевременный preconnect ко множеству внешних доменов. Откроете лишние TCP/TLS, зря перегреете сокеты.

Как измерять эффект: прагматика

Смотрите на метрики, которые действительно отражают пользовательский опыт:

  • LCP — основная целевая метрика. Preload LCP-изображения и приоритизация дают самый заметный эффект.
  • FCP — растёт при корректном preload CSS и раннем старте загрузки шрифтов (с безблокирующим font-display).
  • TTFB — может визуально «расти» при агрессивном preload на одном сокете, но это не обязательно плохо, если LCP/FCP улучшаются.

Водопад в DevTools с Early Hints и preload

Обязательно сравнивайте waterfall «до/после»: порядок запуска запросов, приоритеты, отметки Early Hints, попадания в кэш, размеры и сжатие. Делайте канареечный релиз на части трафика и проверяйте регрессии.

Примеры минимальных настроек

HTML: LCP-изображение и CSS

<link rel="preload" href="/assets/app.css" as="style">
<link rel="preload" href="/assets/hero.jpg" as="image" imagesrcset="/assets/hero@2x.jpg 2x">
<img src="/assets/hero.jpg" width="1200" height="630" fetchpriority="high" alt="...">

Заголовки ответов: Priority и Cache-Control

Priority: u=0, i
Cache-Control: public, max-age=31536000, immutable
ETag: "A1B2C3"
Vary: Accept-Encoding

Nginx: статическая раздача и приоритет (пример)

location = /assets/hero.jpg {
    add_header Priority "u=0, i" always;
    expires 1y;
    add_header Cache-Control "public, max-age=31536000, immutable";
}
location ~* \.(css|js|mjs)$ {
    add_header Priority "u=1" always;
    expires 1y;
    add_header Cache-Control "public, max-age=31536000, immutable";
}

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

Чек-лист перед продом

  • Удалён весь код HTTP/2 Push и отключены соответствующие плагины/директивы.
  • Критичный путь определён, для 2–5 ресурсов настроен preload.
  • LCP-изображение помечено fetchpriority="high", шрифты имеют crossorigin и font-display.
  • Статика версионирована по хэшу, для неё включены долгий TTL и immutable.
  • Приоритеты расставлены (заголовок Priority и/или fetchpriority), негативных побочных эффектов не обнаружено.
  • 103 Early Hints протестирован в вашей инфраструктуре там, где это действительно ускоряет.
  • Измерения показали улучшение LCP/FCP и отсутствие регрессий.

Итог

Классический HTTP/2 Push ушёл — и это хорошая новость. Его место заняли более предсказуемые и управляемые механизмы: декларативный preload, современная приоритизация и сильный кэш. Вместе они дают стабильный выигрыш на первом визите и обеспечивают почти мгновенные повторные заходы. Потратьте день на переезд — и перестаньте «угадывать» за браузер: объявляйте критические ресурсы явно, расставляйте приоритеты и давайте клиентам кэшировать то, что не меняется.

Поделиться статьей

Вам будет интересно

Миграция на PHP 8.3/8.4: депрекейты, ini‑изменения и безопасный откат OpenAI Статья написана AI Fastfox

Миграция на PHP 8.3/8.4: депрекейты, ini‑изменения и безопасный откат

Практический план миграции на PHP 8.3/8.4 для админов и девопсов: где ловятся депрекейты, что пересмотреть в php.ini и FPM, как пр ...
AppArmor vs SELinux для веб‑сервисов: что выбрать и как включить минимум OpenAI Статья написана AI Fastfox

AppArmor vs SELinux для веб‑сервисов: что выбрать и как включить минимум

AppArmor и SELinux закрывают класс рисков, которые не решить одними правами и контейнерами. В статье — практическое сравнение для ...
ARM на VDS: производительность PHP/Node, совместимость и экономия ресурсов OpenAI Статья написана AI Fastfox

ARM на VDS: производительность PHP/Node, совместимость и экономия ресурсов

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