HTTP/2 Server Push с помощью Symfony HttpKernel

HTTP/2 поддерживает фичу под названием Server Push, позволяющую серверу отправлять таблицы стилей, JavaScript и другие статичные ресурсы в клиентский браузер без отдельных запросов.

Традиционно HTML страницы содержат ссылки на различные медиа-файлы, такие как JavaScript, CSS и изображения. Серверное приложение отправляет страницу браузеру, тот интерпретирует страницу и затем загружает с сервера статичные ресурсы.

Ваше серверное приложение, скорее всего, знает о том, какие ресурсы крайне важны для клиента. HTTP/2 Server Push даёт серверу возможность отправить определённые статические файлы прежде, чем клиент даже узнает, что они необходимы. Это приведёт к сокращению времени отрисовки при первой загрузке.

Server Push является дополнительной технологией и не устраняет необходимости ссылаться на таблицы стилей и другие медиа-файлы в ваших страницах. В HTML коде по-прежнему будут ссылки, но первый ответ от сервера будет включать дополнительные заголовки, сигнализирующие о контенте для предзагрузки браузером.

Это улучшенный способ встраивания статичных ресурсов, таких как изображения и CSS, в HTML страницу, поскольку отдельные ресурсы могут кэшироваться на клиенте. Те клиенты, которые не поддерживают Server Push, никак не отреагируют на дополнительные заголовки и продолжат функционировать так же, как и сегодня.

Server Push с помощью Symfony HttpKernel

Компонент Symfony HttpKernel широко распространён в CMS и других веб-приложениях, написанных на PHP. Компонент позволяет легко и структурировано строить HTTP ответы объектно-ориентированным способом. Рассмотрим следующий фрагмент Silex, используемый браузером для рендеринга одного изображения и кнопок «Предыдущее» и «Следующее»:

<?php

$app->get('/images'), function () use ($app) {
    $images = array('/images/1.jpg','/images/2.jpg','/images/3.jpg');
    $response = new JsonResponse($images);
    return $response;
});

В примере выше сервер сначала отправит JSON ответ, и браузер запросит отдельные изображения только тогда, когда они потребуются. Клиентское приложение могло само предварительно загрузить 2.jpg и 3.jpg, но с небольшой модификацией мы можем заставить сервер пушнуть их:

<?php

$app->get('/images'), function () use ($app) {
    $images = array('/images/1.jpg','/images/2.jpg','/images/3.jpg');
    $response = new JsonResponse($images);

    foreach($images as $image){
        $response->headers->set('link','<' . $image . '>; rel=preload; as=image',false);
    }

    return $response;
});

Браузер и сервер, совместимые с HTTP/2 Server Push, загрузят изображения прежде, чем клиент выполнит любой запрос для них. Это выполняется путём отправки дополнительных заголовков link, соответствующих черновой спецификации preload link от W3C. Обратите своё внимание на false параметр, переданный методу set — это разрешает отправку множества заголовков с одним и тем же.

Большинство популярных браузеров сейчас поддерживают HTTP/2, а поддержка серверах продвигается в Apache mod_http2 и Nginx, но пока экспериментально. Вы можете попробовать также использовать H20 для того, чтобы начать работать с HTTP/2 Server Push уже сегодня с помощью PHP.

Запушенные статичные ресурсы не видно в сетевых инспекторах в браузерах на основе Blink, таких как Opera или Chrome, так что лучший способ увидеть, проходят ли запросы, это следить за логом обращения к серверу.

Примечание: Заголовки, отправленные с использованием vanilla PHP (или любого другого языка), будут функционировать также.

Не важно всё

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

Трата пропускной способности путём отправки уже кэшированных элементов (клиентом) может быть проблемой для сервера и браузеров. Веб-сервер H20, например, реализует метод под названием CASPer (cache-aware server-push) для предотвращения такой ситуации:

H20 поддерживает цифровой отпечаток кэша веб-браузера и отменяет server-push, предложенный обработчиками, если известно, что клиент находится в possention состоянии и метод CASPer активирован. Цифровой отпечаток сохраняется в cookie, названном h2o_casper с помощью Golomb-compressed sets (a compressed encoding of Bloom filter).

Так же как с оптимизациями HTTP/1.1, такими как domain sharding и другими хаками, я уверен, что мы увидим изобретательные способы использования (или злоупотребления) Server Push в ближайшие годы.

Пушинг данных инициализации в JSON формате для клиентской стороны приложения является жизнеспособной альтернативной Изоморфному Рендерингу для повышения производительности первоначальной загрузки одностраничных приложений, построенных с помощью Vue, Angular или React.

Примечание

Данная статья является авторским переводом «HTTP/2 Server Push (with the Symfony HttpKernel) | Symfony Finland».

Комментарии

  1. Буранчик пишет:

    >React
    Это который совместно с Facebook разрабатывают?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *