
Drupal 8, Cache & Rock N' Roll |
21.06.16 12:49 |
Ну и чо там?Из Symfony в Drupal 8 привита всеобщая кэшируемость. Теперь для любого объекта, который участвует в рендеринге, можно задать свои параметры кэширования. Выглядит так: '#cache' => [
'keys' => ['entity_view', 'node', 5, 'teaser'], 'contexts' => ['languages', 'timezone'], 'tags' => ["node:5", 'user:3'], 'max-age' => Cache::PERMANENT, ], Всего 4 параметра (указывать все необязательно): keys – массив значений, из которых будет сформировано название для кэша (ID). Типичный набора: contexts –зависимость от эм.. контекста, например языка и временной зоны. Для тех, кто сечет в HTTP заголовках, в качестве его аналогии приводят Vary. Еще примеры возможных значений: cookies, route, session, url, user и т.д. Можно задавать более конкретную привязку, например user.permissions – зависимость только от прав пользователя, или url.query_args:foo – зависимость от параметра foo в адресной строке запроса.При их обработке происходит оптимизация. Например: tags – зависимость от конкретных объектов, например от 5-ой ноды, или пользователя с id = 3. Интересно, что можно задавать значения типа config:block_list (зависимость от конфигурации блоков), или config:filter.format.basic_html. А еще node_list. max-age – время хранения кэша в секундах (0 – не хранить, Cache::PERMANENT (-1) – без ограничения) Не надо бла-бла, давай примерЗадача: разработать блок, который будет выводить значение параметра xxx переданного через адресную строку. При рендеринге блока нет трудоемких задач, но его результат все равно будем кэшировать (иначе нафига этот пример). Чтобы убедиться, что кэш работает, кроме значения выведем еще и время, когда это значение было сохранено.
Пример работы: my.site?xxx=Kate -> Kate (2016-02-07 11:11:11)
my.site?xxx=Ann -> Ann (2016-02-07 22:22:22) my.site/node/666?xxx=Ann -> Ann (2016-02-07 22:22:22) my.site?xxx=Kate -> Kate (2016-02-07 11:11:11) Т.е. если xxx повторяется – значение берется из кэша, независимо от времени и страницы, и наоборот, стоит xxx измениться, и блок выдает другое значение (которое тоже кэширует). Правда если зайти под другим пользователем, то будет другой кэш, хоть никакой зависимости от пользователей и не указано. И так и не понял, как задать Но, можно делать свой кэш с нужным значением и ключами: <?php Помни! Если кто-то вобьёт мильярд разных вариантов xxx – ничем хорошим это не закончится. Прямая зависимость кэша от столь легко меняющейся (и бесконечновариантной) зависимости – крайне не рекомендуется. Еще примерВ блоге Acquia Dev есть пример, в котором рассматривается конвертация изображения в asci-символы. Вот краткая выжимка: Как тебе такое решение? <?php Здесь клёвая картинка ламы будет преобразована в ASCII символы. И, будь уверен, преобразование просто прекрасно! Но сейчас разговор не об искусстве ASCII. Динамическая генерация данных на основе изображения, разве это не медленно, спросишь ты. Ясен день! В конце-то концов, как следует преобразовать пушистую ламу в набор символов не так-то и просто. Нет, без шуток, можно придумать кучу случаев затратного рендеринга (требующего сложных вычислений и кучи запросов к бд). Так что кэширование результатов здорово бы помогло. И вот как это можно устроить: <?php Что за магические значения?Завязывать кэш на конкретные значения (5-ую ноду, 3-го пользователя) – это, конечно, не солидно. А главное, вряд ли нужные значения известны. Поэтому в реальности, конечно, всё описывается программно. Например, нужно связать кэш со списком нод из какой-то выборки <?php Яма, яма, яма, ямллл…Кстати, простые настройки можно указывать и через YML renderer.config:
auto_placeholder_conditions: max-age: 0 contexts: ['session', 'user'] tags: [] Настройка через API:$metadata = new CacheableMetadata();
$metadata->setCacheContexts(['qux']) ->setCacheTags(['foo:bar']) ->setCacheMaxAge(600); Хочу свой рендеринг с кешем и зависимостямиВот, пожалуйста:
Какие есть еще API?Теги и контексты – обычные массивы, и ничто не мешает их склеить обычным сложением Entity и Config – готовы, а ты?У всех entity или configuration уже настроены параметры кэширования. Получить их можно так:
Аналогично для contexts и max-age Что там есть в Examples/cache_exampleХоть там todo больше, чем кода, но можно глянуть как вручную сохранять/получать/удалять кэш: <?php Где cacheBackend - это объект реализующий интерфейс CacheBackendInterface. Так кому, что и почему надо знать?При описании «революционных изменений» Drupal 8, часто упоминают «кэширование по умолчанию». Но это не просто кэширование. Два модуля, Internal Page Cache и Dynamic Page Cache затащили это дело на новый уровень. Вот как описывает историю их создания ведущий разработчик Вим Лирс (вкратце): Как-то Дрис начал парить мне голову вопросами о ESI. Я сказал, что то, что у нас называется "поддержкой ESI" - бред, но есть реальный шанс сделать хорошо. Дриса это так проняло, что он даже выложил пост :) А мне пришлось изрядно напрячь башку, чтобы реализовать то, что посулил в запале. Сначала наша команда довела до ума кэш тэги, благодаря чему Page Cache (ныне Internal Page Cache) стал работать так хорошо, что мы включили его в сборку и включили по умолчанию. А затем добили и контексты кэша. Это далось не просто, пробовали и так и сяк. В резульате на пару с Фабьеном запили через пузырёк. Потом еще 7 месяцев Конечно, еще есть над чем работать, напрягает и время перед запуском и всякая другая лабуда, но у нас еще есть идеи на этот счет. Кстати, как вам BigPipe? И еще разТо, что эти модули включены по умолчанию, означает, что каким бы ты ни был лохом, кэширование на сайте Drupal 8 будет огонь! Только не выключай их. Хотя, если для анонимных пользователей нужны разные результаты (например, с учетом их сессии), то Internal Page Cache придется отключить (либо мутить через AJAX), но это уже другая история. А в этой истории речь о том, что теперь больше не нужны никакие танцы с Authcache, где нужно учитывать весь код сайта. Более того, опять пошли разговоры, что владелец сайта (админ, маускликер, сайт-билдер) может забыть, что значить фраза «очистить кэш». Поскольку теперь разработчики модулей могут и должны сами настроить зависимости кэша. Контриб-модули даже обязаны предоставить тесты на годность в режиме кэширования. Но если Dynamic Page Cache мешает запалу разработки, можно временно его отключить, для этого в папке sites/название_сайта/ создается settings.local.php с кодом:
Когда это будет в 7-ке?Никогда. В Drupal 7 не появится мгновенного обновления кэша (в Drupal 8 кэш обновляется сразу по факту устаревания, не дожидаясь запроса, ога). Не появится Dynamic Cache Page. И не будет BigPipe. Как-то так. А где же та фраза?«There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Karlton» Склад ссылок, которых здесь еще не было (хотя быть должны)https://www.drupal.org/developing/api/8/cache |