Главная » Статьи » Критическая миссия: Оптимизация CSS для CDN

Критическая миссия: Оптимизация CSS для CDN

Критическая миссия: Оптимизация CSS для CDN

От автора: в Filament Group мы рекомендуем использовать подход критического CSS во многих наших проектах. Часто эти проекты используют для доставки CDN, и нам нужно обрабатывать каждую конкретную реализацию немного по-другому, чтобы задействовать различные CDN и их функции. В этой статье мы подробно рассмотрим эту проблему и предоставим руководство, как делается оптимизация CSS для нескольких CDN.

Обзор

Критический CSS — это метод, используемый для получения вышеописанного CSS для HTML-страницы в первом 14-килобайтном окне запроса страницы. Это позволяет браузеру быстрее выполнять осмысленный рендеринг контента. Полный CSS, т. е. CSS для всей страницы, включая все вышеперечисленное, загружается позже и, надеюсь, кэшируется браузером.

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

Это приводит к созданию, по меньшей мере, двух страниц для каждого URL-адреса. Одна страница — с вышеописанным и полным CSS для первого запроса, когда полный CSS не кэшируется, и одна — с полным CSS для последующих запросов, когда он кэшируется.

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

Пограничный контент

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

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

Условная страница

Определение на сервере, когда полный CSS кэшируется браузером, часто выполняется с помощью эвристики. Один из подходов, с которыми мы экспериментировали в последнее время — использовать куки HttpOnly, предоставляемый в ответ на запрос для полного файла CSS. Предполагая, что браузер будет кэшировать ответ с полным CSS, сервер может избежать включения вышеописанного CSS в более поздние запросы страницы, проверяя куки.

Следующий фрагмент конфигурации Apache устанавливает куки на основе запроса для полного файла CSS.

<IfModule mod_headers.c> <If "%{HTTP_COOKIE} !~ /visited\=VERSION/ && %{DOCUMENT_URI} =~ /full\.css/"> Header set Set-Cookie "visited=VERSION; Path=/; HttpOnly" </If>
</IfModule>

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

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

<!--#if expr="$HTTP_COOKIE=/visited\=VERSION/"--> <link rel="stylesheet" href="/path/to/full.css?VERSION">
<!--#else --> <style> /* inlined critical css */ </style> <!-- предварительная загрузка полного css и применение его. если не поддерживается, ссылка rel=preload с as=style полифиллируется через js --> <link rel="preload" href="/path/to/full.css?VERSION" as="style" onload="this.onload=null;this.rel='stylesheet'"/> <noscript> <link rel="stylesheet" href="/path/to/full.css?VERSION"> </noscript>
<!--#endif -->

Вместе эти фрагменты кода будут создавать две страницы в зависимости от состояния загруженного куки, и любое кэширование CDN содержимого должно кэшироваться и отвечать обеими страницами в соответствии с куки visited.

Конфигурация CDN

На CDN нам нужны пограничные серверы для повторной проверки того, что страницы меняются в зависимости от значения куки visited, и соответственного кэширования обеих версий. Ниже приводится описание того, как это сделать для Akamai, CloudFront и Fastly.

Akamai

В веб-интерфейсе Akamai ключ кэша можно изменить, настроив конкретное «свойство». В редакторе диспетчера свойств, либо в правиле по умолчанию, либо в другом подходящем правиле, которое соответствует кэшированному контенту, добавьте следующее поведение «Cache ID Modification»:

Обратите внимание, что файл куки «Не требуется для кэширования», потому что мы хотим, чтобы начальные запросы не содержали кэшированный файл куки.

CloudFront (AWS)

Cloudfront можно настроить для пересылки белого списка файлов куки на сервер и кеширования на основе каждого из значений куки. После выбора дистрибутива отредактируйте один из вариантов поведения для распространения и измените значение «Forward Cookies» на Whitelist и добавьте куки visited.

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

Fastly

Fastly использует Varnish Configuration Language для настройки поведения пограничных серверов. Вы можете использовать следующий фрагмент, чтобы изменить ключ кэша для учетной записи для куки visited. Он использует регулярное выражение и добавляет результат в ключ кэша.

sub vcl_hash { set req.hash += req.url; set req.hash += req.http.host; set req.hash += regsub(req.http.cookie, ".*visited=([^;]+);.*", "\1");
#FASTLY hash return (hash);
}

Для получения дополнительной информации ознакомьтесь с их отличной документацией по ключу кэша VCL.

Автор: John

Источник: https://www.filamentgroup.com/

Редакция: Команда webformyself.