HTTPCache

Осуществляет полное кеширование страниц.

Документация

Читать

Компонент HTTPCache осуществляет «агрессивное» кеширование, т.е. в кэш запоминаются страницы целиком.

При таком виде кэширования обычно возникает ряд проблем:

  • Проблема страниц с динамическим блоками. Например, если в тело страницы непосредственно был вставлен код баннера, который менялся случайным образом, то кеширование страницы приводило к тому, что смена баннеров переставала работать.
  • Проблемы персонализированных страниц или страниц с блоками, вывод которых зависит от каких-то условий.

В компоненте реализованы методы, решающие эти проблемы.

Для работы компонента не требуется какая-либо установка дополнительных компонентов, кроме случаев, где содержимое блоков требуется запрашивать по AJAX. Тогда можно воспользоваться готовым компонентом AjaxBlock.

Применение событий Events

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

В компоненте есть возможность влиять на формирование уникального ключа для обрабатываемой страницы. Для этого создано специальное событие cms.components.http_cache.hash. Например, допустим, что тип корзины на сайте лежит в сессии, тогда

Events::add_listener('cms.components.http_cache.hash', function($url, &$salt) {
	$session = WS::env()->request->session();
    	$salt .= '|' . $session['shop_type'];
});

Где первым аргументом функции передается ссылка, для которой формируется уникальный хеш/ключ, а вторым аргументом передается так называемая «соль» - строка к которой можно добавлять произвольные параметры.

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

Модификатор CACHE в HTTPCache

В библиотеке TAO появилась возможность указывать модификатор для вставки. Модификатор в данном случае - это просто дополнительная метка, тег которой указывается через двоеточие после названия вставки. При реализации вставки можно использовать модификатор для выполнения каких-то специфичных действий.

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

Примером может служить вставка баннера из соответствующего компонента:

%BANNER:CACHE{main_slogan}

Или, например, персонализированная информация о корзине пользователя из компонента Shop:

%CART_TOTAL:CACHE{}

Таким образом, для обработки динамических блоков на странице необходимо создать вставку (если ее еще нет) и использовать ее с модификатором :cache. Стоит обратить внимание, что если отключить HTTCache, то сайт продолжит работать, даже если в коде останутся модификаторы.

Кэширование блоков вывода в шаблоне

В компоненте появилась новая возможность кеширования блоков вывода в шаблоне. Рассмотрим пример:

<?php $key = md5(serialize($item->attrs)); ?>

<?php if (!Component_HTTPCache::block()->start("item-full:{$item->id}", $key, $this)) { ?>
	<div class="catalog-item">
    		HTML CODE
    		<?= $this->partial('..') ?>
    		<?php $this->use_scripts(''); ?>
  	</div>
<?php }

echo Component_HTTPCache::block()->stop("item-full:{$item->id}");
?>

Здесь есть два вызова Component_HTTPCache::block()->start и Component_HTTPCache::block()->stop, а также код вывода обернут в if.

Метод start проверяет, есть ли кеш для текущего блока и, соответственно, возвращает значение true / false. Если для блока уже есть кеш, тогда обработка не происходит и мы сразу переходим к вызову метода stop, который вернет закешированный html-код. Если же метод start не обнаружит нужного кеша, то код внутри конструкции if обрабатывается и его результат сохраняется в кеш при вызове метода stop.

Как видно из примера, внутри кешируемого блока можно вызывать методы шаблона, такие как partial или use_... и они корректно обработаются.

В метод start передаются следующие аргументы:

  • $name - имя кешируемого блока.
  • $key - уникальный ключ для текущего блока (по паре $name+$key формируется имя кеша).
  • $view - ссылка на текущий шаблон (не обязательный, но желательный параметр).
  • $timeout - специфичное для этого блока время жизни кеша.

В метод stop передаются следующие параметры:

  • $name - имя блока.

В приведенном примере $name формируется от id материала, а $key от всех остальных параметров. Если формирование ключа для блока очень сложное, то в качестве ключа можно передать объект Core::call, например:

$key = Core::call('App.Utils', 'item_key', $item->id);

Тогда при формировании ключа будет вызван метод App.Utils::item_key($item->id).

Таким образом можно осуществлять кеширование блоков, даже если отключено стандартное кешировании страниц в HTTPCache.

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

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

Настройки

У компонента значительно расширился состав доступных настроек. Настройки по умолчанию, которые можно переопределить стандартными механизмами Core::configure:

// app/config/modules.php

'Component.HTTPCache' => array(

	// включить/выключить кеширование страниц
	'page_cache' => true,

	// время жизни кеша
	'lifetime' => 3600,

	// какие страницы не кешировать
	'disallow' => array(
		'/component-static/*',
		'/admin/*',
	),

	// какие GET параметры игнорировать
	'ignore_get' => array('XDEBUG_PROFILE'),

	// параметры проверки запроса
  	'request_check' => array(

		// разрешенные HTTP методы для кеширования
    		'method' => array('get'),

		// true - ajax запросы не кешируются
    		'ajax' => true,

		// true && WS::env()->auth->user -- запрос не кешируется
    		'user' => true,

		// не кешировать админку
    		'admin_request' => true,

		// при установке этих cookie кеширование отключается
    		'cookie' => array('auth_login', 'auth_password'),

		// scheme -- разрешенные схемы запроса
    		'scheme' => array('http'),
	),

	// проверка отклика для которого сохранить кеш
  	'response_ckeck' => array(
    		// список корректных статусов
    		'status' => array(200),
  	),

	// включить отладочный режим
  	'debug' => false,

// настройки блочного кеширования
  	// куда сохранять блочный кеш
  	'cache' => 'fs://../cache/http_cache',

  	// использовать ли блочный кеш
	'block_cache' => true,

	// время жизни блочного кеша
  	'block_lifetime' => 3600,
)

Допустим нам нужно разрешить кеширование для зарегистрированных пользователей, тогда:

//app/components/HTTPCache/app/config/component.php
'Component.HTTPCache' => array(
	  'request_check' => array(
    		'cookie' => array(),
    		'user' => false,
  	   )
)

При включении debug-режима в настройках становится возможным просматривать страницу с отключенным постраничным кешем, если в GET-параметры добавить http_clear=1.

Вывод в администраторе сайта

У компонента появился административный интерфейс в виде табличного контроллера по адресу /admin/http_cache/, где можно удалить или даже отредактировать кеш страницы.

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

Вставка динамических блоков. Компонент AJAXBlocks

Одним из самых очевидных способов добавить динамические блоки на кешируемые страницы - это запрашивать содержимое блоков по AJAX. Что бы несколько упростить реализацию такого подхода был разработан дополнительный компонент AjaxBlocks.

Если в HTML-странице к элементу добавить атрибут data-ab-url где указать ссылку, то после загрузки страницы, будет сделан запрос по этому адресу, а полученный ответ подставится в содержимое элемента. Кроме атрибута необходимо указать класс ajax-block-insertion.

<div class="ajax-block-insertion" data-ab-url="/url/to/get/html/content/for/div">
	Содержимое, которое покажется при первой загрузке
</div>

В таком случае, нужно обеспечить, чтобы по указанному урлу отдавался корректный html. Если у элемента кроме data-ab-url есть какие-то другие data-атрибуты, то они передадутся как GET-параметры.

В случае, если на странице таких блоков будет много, то делать много запросов не очень хорошо. Для решения этой проблемы, вместо data-ab-url можно указать data-ab-name с именем блока для запроса. Тогда компонент скомбинирует все в один запрос. Чтобы это работало, необходимо зарегистрировать обработчик для указанного в data-ab-name имени одним из способов:

// app/components/AjaxBlocks/app/config/blocks.php

return array(
	'test' => 'Component.AjaxBlocks.App.Blocks.Test',
);

// app/components/ComponentName/config/ajax_blocks.php
return array(
  	'blocks' => array(
    		'item-teaser' => 'App.Utils::item_teaser',
 		),
);

// где-то
Component_AjaxBlocks::append_block($name, $callback);

Особенности кэширования вставки HEAD

Кэширование заголовочного блока имеет свои особенности.

Рассмотрим на примере: предположим, что на сайте выводятся формы из компонента Forms, который содержит поле jsprotect. После запуска кэширования формы отработают только у первого посетителя, так как данные для поля jsprotect берутся из сессии конкретного пользователя. Можно воспользоваться модификатором CACHE для вставок FORM.

Формы перестанут кэшироваться и, вроде бы, должны начать работать. Но тогда появляется ошибка: у форм пропадают стили и не подключаются js-скрипты. Это происходит, потому что некэшируемые вставки обрабатываются после генерации всего контента страницы, в том числе блока HEAD с подключением скриптов и стилей. То есть, на стадии формирования HEAD еще не известно, будет ли что-то добавлено из форм в заголовок. Так же, в некэшируемых вставках не будет работать добавление параметров в TAO_Settings, inline js и css и тд.

Для решения этой проблемы необходимо кэшировать вставку HEAD.

%HEAD:CACHE{}

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

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

%HEAD:CACHE{files}
%HEAD{^files}

Важно! После обновления ТАО до последних версий могут возникнуть проблемы с подключением стилей и скриптов из вставок. Во избежании возникновения ошибок при загрузке стилей или скриптов, необходимо использовать следующие вставки:

%HEAD:CACHE{files_css}
%HEAD:CACHE{files_js}
%HEAD{^files_css, files_js}

Для проектов, где ТАО было обновлено до последних версий и были использованы вставки HEAD, необходимо их заменить на описанные выше.

Все версии

Обращаем ваше внимание, что установка и обновление компонентов штатным способом осуществляется из системы управления вашим сайтом ("Библиотека компонентов"). Данный раздел несет прежде всего информационную функцию. Однако, вы можете скачивать инсталляционные пакеты компонентов в целях ознакомления или в случае если функционирование библиотеки компонентов по какой-то причине затруднено.


Версия Дата
2.0.10 29.01.2018
2.0.9 13.11.2015
2.0.8 03.11.2015
2.0.7 21.10.2015
2.0.6 13.10.2015
2.0.5 25.09.2015
2.0.4 22.04.2015
2.0.3 26.01.2015
2.0.2 23.12.2014
2.0.1 22.12.2014
2.0.0 16.12.2014
1.0.2 01.11.2013
1.0.1 17.10.2013
1.0.0 09.10.2013