Евгений Никитин Евгений Никитин

Русский English

Про кеш в Drupal 10

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

Drupal в начале начинает рендерить страницу, затем layout, потом блоки и заканчивает содержимыми блоков. Каждая контентная часть имеет определенные настройки кеша - время жизни, кеш теги и кеш контекст (основы Cache API). Drupal собирает параметры кеша каждого элемента, и общие параметры для ответа вы можете увидеть в заголовке страницы если включить параметр http.response.debug_cacheability_headers в services.yml.

parameters:
  http.response.debug_cacheability_headers: true

Параметры кеша в заголовке ответа

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

По-умолчанию Drupal кеширует блоки с контентом. Но также можно закешировать ответ целиком. В Drupal 10 есть для этого два модуля - Internal page cache и Internal Dynamic Page Cache.

Internal Page Cache модуль.

Данный модуль кеширует запросы от анонимных пользователей. Все анонимные пользователи будут видеть один и тот же ответ/страницу. Если нужно показать какую-то персональную информацию на странице анонимному пользователю, то нужно либо отключить модуль, либо использовать ajax запрос чтобы получить нужный блок.

Пользователь считается анонимным если у него нет открытой сессии. Если у пользователя есть куки вида SSESS5a5813d2457b0cadd870939bdf9bbfd0, то значит сессия у пользователя открыта и запросы не будут кешироваться модулем Internal page cache.

Также нужно учитывать, что кешируются только GET and HEAD запросы (смотрите \Symfony\Component\HttpFoundation\Request::isMethodCacheable). По-умолчанию Drupal использует POST метод для ajax запросов, поэтому если вы хотите кешировать ajax запросы, то для них следует использовать GET метод.

Также не кешируются запросы, которые были инициированы из командной строки, например через drush.

Если страница была выдана из кеша, то в заголовке ответа будет запись X-Drupal-Cache: HIT.

Internal page cache устанавливает срок жизни кеша только в том случае если для ответа такой срок жизни был установлен - $response->setExpires(\DateTimeInterface $date). Значения max age у блоков игнорируются (но это может поменяться в Drupal 11). Кеш будет сохранен до тех пор пока какой-либо из тегов кеша не будет признан недействительным, либо же кеш страниц не будет очищен.

Internal Dynamic Page Cache модуль

Данный модуль будет полезен если на странице присутствует динамический (персонализированный) контент. По-умолчанию, контент считается динамическим если у него установлен контекст session или user, либо же срок жизни 0. Это определяется в core.services.yml и, при необходимости, настройки можно поменять (например, указать определенные теги):

renderer.config:
  auto_placeholder_conditions:
  max-age: 0
  contexts: ['session', 'user']
  tags: []

Если контент динамический и для него определен #lazy_builder обработчик (для блоков он определяется по-умолчанию в \Drupal\block\BlockViewBuilder), то при рендеринге страницы такой блок будет заменен на строку-заменитель (placeholder). Страница со строками-заменителями будет сохранена в кеш. При запросе, страница будет взята из кеша, а вместо заменителей будут подставлены сгенерированные блоки для конкретного пользователя.

Пример блока, который не будет закеширован

При использовании контекста user необходимо учитывать, что все анонимные пользователи это один и тот же пользователь. Если нужно показывать разный контент анонимным пользователям, то лучше использовать контекст session.

Чтобы определить использовался ли Dynamic Page Cache нужно посмотреть в заголовок ответа - там должна быть запись X-Drupal-Dynamic-Cache: HIT если страница взята из кеша.

Про настройку “Browser and proxy cache maximum age”

Важно знать, что настройка “Browser and proxy cache maximum age” на странице /admin/config/development/performance используется для установки параметра Cache-Control в заголовке страницы, которые читаются только браузером или реверс прокси системами (например Varnish).

Ниже код из \Drupal\Core\EventSubscriber\FinishResponseSubscriber::setResponseCacheable(), где это используется:

$max_age = $this->config->get('cache.page.max_age');
$response->headers->set('Cache-Control', 'public, max-age=' . $max_age);

На поведение Internal page cache и Internal Dynamic Page Cache эта настройка никак не влияет.