Drupal и HTTP / 2: время экспериментировать

Автор Джефф Эпплби

HTTP / 2 - это довольно круто, он может снизить использование ресурсов и повысить производительность Интернета. Он поддерживается Firefox, Chrome и Edge, а также Safari в OSX 10.11+. Его поддерживают веб-серверы Apache и Nginx. Такие сети CDN, как Cloudflare и Akamai, поддерживают его. Наличие бесплатных сертификатов TLS от Let's Encrypt снимает затраты как препятствие для более широкого внедрения. HTTP / 2 также представляет некоторые новые функции для использования приложениями, и я хотел изучить возможности Drupal 8, чтобы воспользоваться этими изменениями и улучшениями.

Одна деталь HTTP / 2, которая мне показалась особенно интересной, заключается в том, что практика объединения ресурсов больше не обязательно является полезной оптимизацией. Некоторые сайты объединяют все ресурсы CSS и JavaScript, используемые где-либо на сайте, в один файл для каждого, но не все компоненты в этом файле могут использоваться на каждой странице. В идеале увеличение времени загрузки файла большего размера компенсируется сокращением времени, необходимого для установления нескольких подключений, а также предотвращает задержку передачи ограничением одновременных подключений при большом количестве ресурсов.

Drupal поставляется с возможностью объединения CSS и JavaScript, которые требуются для отдельных страниц, но если компонент используется только на подмножестве страниц, это может привести к необходимости загрузки объединенного файла большего размера при посещении новых страниц. Развертывание нового кода также делает недействительными все ранее сгенерированные файлы, даже если был изменен только один из исходных файлов.

HTTP / 2 отправляет данные по одному соединению с потоком для каждого ресурса, избегая накладных расходов на создание нескольких соединений и ограничений на одновременные соединения. Спецификация рекомендует минимальный лимит 100 одновременных потоков, что является значительным увеличением по сравнению с лимитом в 6–8 подключений, который браузеры в настоящее время применяют. Чтобы большое количество одновременных потоков не приводило к задержкам, поскольку они борются за пропускную способность, приоритеты потоков дают браузеру улучшенный контроль над тем, какие элементы он хотел бы, чтобы сервер отправлял первым, без задержки последующих запросов, если один из них задерживается. Если каждый требуемый ресурс указан индивидуально, а не объединен, воспринимаемая производительность должна быть улучшена, поскольку будут загружены только некэшированные данные, действительно необходимые для страницы.

Текущие рекомендации, как правило, состоят в том, чтобы продолжать объединять ресурсы, чтобы избежать наказания старых клиентов, пока принятие HTTP / 2 не станет достаточно большим. Однако это ограничивает возможность максимально использовать возможности HTTP / 2 новых браузеров сейчас и по-прежнему будет влиять на старые браузеры после переключения. Я хотел изучить возможность обслуживания страниц для пользователей на основе оптимального опыта для возможностей их браузера с помощью модуля для Drupal 8.

Модуль Drupal

Усовершенствованная система кэширования Drupal 8 использует контексты кэша, чтобы гарантировать, что элементы кэшируются в соответствии с тем, что делает каждый компонент уникальным, позволяя динамическому кешу страниц обрабатывать и отображать только те части страниц, которые уникальны для каждого запроса. Некоторые примеры контекстов - это язык компонента или то, зависит от того, отличается ли компонент для аутентифицированных и анонимных пользователей. В этом случае необходимо создать контекст кеширования для определения того, был ли запрос сделан с помощью HTTP / 2 на основе данных, предоставленных с веб-сервера.

Объектно-ориентированная архитектура Drupal 8 разбивает код на небольшие целенаправленные части, но, что наиболее важно, позволяет легко расширять или заменять эти компоненты. В этом случае обработчик вложений по умолчанию проверяет, работает ли сайт в режиме обслуживания и включен ли параметр конфигурации для объединения CSS и JavaScript. Затем он использует эту информацию, чтобы сообщить преобразователю ресурсов, должен ли он возвращать исходные файлы или объединенные версии для включения на страницу. Обработчик вложений, поддерживающий HTTP / 2 просто добавляет дополнительное условие на основе результата оценки запроса в контексте кэша HTTP / 2 для определения правильных файлов.

Это действительно хорошая идея?

Всего байтов

Drupal немного оптимизирует CSS, удаляя комментарии и лишние пробелы. Поскольку все оптимизации для запросов HTTP / 2 отключены, это означает, что они передадут немного больше данных. В идеале запросы HTTP / 2 могут иметь такую ​​же оптимизацию минимизации, применяемую к отдельным активам, чтобы разница в размере передачи была минимальной.

Проблемы с кешем

Динамический кеш страницы не кэширует разметку вложений страницы, поэтому он будет генерировать один компонент страницы, который различается между протоколами при каждом запросе, без необходимости знать сам протокол запроса. Однако существует проблема с анонимным кешированием страницы Drupal, поскольку он работает исключительно с URL-адресом запроса, полностью игнорируя протокол, и обслуживает ту версию каждого URL-адреса, которая была запрошена и кэширована в первую очередь. По мере того, как посетители перемещаются по сайту, они могут переключаться между страницами, оптимизированными для каждого из двух протоколов, увеличивая объем данных, которые каждый должен загрузить. Кэш страницы в настоящее время не позволяет подключиться к критериям для кеширования вариантов страницы, поэтому для преодоления этого ограничения потребуется настраиваемая служба кеширования страниц.

Уровни внешнего кеширования, такие как Varnish или Cloudflare, будут иметь ту же проблему, что и внутренний кеш страницы, поскольку они также работают в основном на основе URL-адреса. Стандартный способ сообщить критерии, по которым страница может отличаться от URL-адреса, заключается в том, что сервер указывает заголовок Vary, который определяет заголовки, предоставляемые браузером, такие как 'Accept-Encoding' или 'Cookie '. Используя заголовок Vary, браузер и другие кэши могут определить, может ли запрос быть обработан на основе существующих данных или требуется новый запрос к серверу. Поскольку протокол соединения и заголовки HTTP работают на разных сетевых уровнях, нет заголовка, который можно было бы добавить в Vary, чтобы различать запросы HTTP 1.1 и HTTP / 2. Кроме того, хотя браузеры будут подключаться к уровню кэширования с помощью разных протоколов, уровень кеширования будет подключаться только к исходному серверу по одному протоколу. Пользовательский сервер Varnish может быть настроен на передачу протокола из браузера и кэширование соответствующих вариантов, но более общие решения, такие как Cloudflare, не имеют такой возможности.

В конечном итоге это сужает любые преимущества предоставления контента, специфичного для HTTP / 2, сайтам, которые не могут использовать внутренний кеш страниц Drupal и не используют какой-либо внешний кеш, что может иметь значительные последствия для производительности, которые затмевают преимущества любой оптимизации контента. Текущая рекомендация продолжать объединять ресурсы до тех пор, пока не будет широко распространен HTTP / 2, если вы не заинтересованы в экспериментах и ​​не имеете значительного контроля над всеми слоями между вашим веб-сервером и браузером пользователя.

Загляните в репозиторий модуля на Github

Вы уже экспериментировали с HTTP / 2? Что вы думаете об этом? Дайте нам знать в комментариях ниже. И обязательно ознакомьтесь с нашими работами здесь или подайте заявку на присоединение к нашей команде здесь.