mirror of
https://github.com/yiisoft/yii.git
synced 2026-03-12 02:56:55 +01:00
120 lines
8.2 KiB
Plaintext
120 lines
8.2 KiB
Plaintext
Кэширование страниц
|
||
===================
|
||
|
||
Кэширование страниц — это кэширование всего содержимого страницы. Кэширование
|
||
страниц может встречаться в различных местах. Например, выбрав соответствующий
|
||
странице заголовок, браузер пользователя может кэшировать просматриваемую
|
||
страницу на некоторое время. Веб-приложение также может само хранить содержимое
|
||
страницы в кэше.
|
||
|
||
Кэширование вывода
|
||
------------------
|
||
|
||
Кэширование страницы может быть рассмотрено как частный случай [кэширования
|
||
фрагмента](/doc/guide/caching.fragment). Из-за того что содержимое страницы
|
||
часто генерируется применением макета к представлению, кэширование не будет
|
||
работать, если мы просто вызовем в макете методы
|
||
[beginCache()|CBaseController::beginCache] и
|
||
[endCache()|CBaseController::endCache]. Причина этого в том, что
|
||
макет применяется при вызове метода [CController::render()] *после*
|
||
формирования содержимого представления.
|
||
|
||
Для кэширования всей страницы мы должны пропустить этап формирования
|
||
содержимого страницы. Для выполнения этой задачи мы можем использовать класс
|
||
[COutputCache] как [фильтр](/doc/guide/basics.controller#filter) действия.
|
||
В коде ниже показано, как можно сконфигурировать фильтр кэша:
|
||
|
||
~~~
|
||
[php]
|
||
public function filters()
|
||
{
|
||
return array(
|
||
array(
|
||
'COutputCache',
|
||
'duration'=>100,
|
||
'varyByParam'=>array('id'),
|
||
),
|
||
);
|
||
}
|
||
~~~
|
||
|
||
Вышеприведённая конфигурация создаёт фильтр, применяемый ко всем
|
||
действиям контроллера. Мы можем ограничить его применение одним или
|
||
несколькими действиями, используя оператор `+`.
|
||
Подробнее с работой фильтров можно ознакомиться в теме
|
||
[фильтры](/doc/guide/ru/basics.controller#filter).
|
||
|
||
> Tip|Подсказка: Мы можем использовать класс [COutputCache] в качестве фильтра,
|
||
поскольку он наследует класс [CFilterWidget], т.е. оба этих класса одновременно
|
||
являются и виджетами, и фильтрами. Фактически, способ работы виджета очень похож
|
||
на работу фильтра: виджет (фильтр) выполняется до того, как любое вложенное
|
||
содержимое (действие) будет сформировано (выполнено), а выполнение виджета
|
||
(фильтра) заканчивается после того, как вложенное содержимое (действие)
|
||
будет сформировано (выполнено).
|
||
|
||
HTTP-кэширование
|
||
----------------
|
||
|
||
В дополнение к кешированию всего вывода действия контроллера в Yii с версии
|
||
1.1.11 есть [CHttpCacheFilter]. Данный фильтр отсылает рассматриваемые далее
|
||
HTTP-заголовки, которые говорят клиенту (чаще всего браузеру), что содержимое
|
||
страницы не менялось с последнего запроса. В этом случае серверу нет необходимости
|
||
повторно формировать и отсылать страницу. [CHttpCacheFilter] настраивается
|
||
также, как и [COutputCache]:
|
||
|
||
~~~
|
||
[php]
|
||
public function filters()
|
||
{
|
||
return array(
|
||
array(
|
||
'CHttpCacheFilter + index',
|
||
'lastModified'=>Yii::app()->db->createCommand("SELECT MAX(`update_time`) FROM {{post}}")->queryScalar(),
|
||
),
|
||
);
|
||
}
|
||
~~~
|
||
|
||
Приведённый выше код добавит заголовок `Last-Modified` с значением, равным
|
||
последней дате изменения записи. Также вы можете использовать
|
||
[CHttpCacheFilter::lastModifiedExpression] для того, чтобы задать значение
|
||
`Last-Modified` при помощи выражения PHP.
|
||
|
||
> Tip|Подсказка: Как [CHttpCacheFilter::lastModifiedExpression], так и
|
||
[CHttpCacheFilter::lastModified] могут быть принимать как Unix timestamp в виде
|
||
целого числа, так и дату строкой в понятном человеку формате. Если дату может
|
||
разобрать [strtotime()](http://php.net/manual/ru/function.strtotime.php), то
|
||
никаких дополнительных преобразований не требуется.
|
||
|
||
Похожим образом, через [CHttpCacheFilter::etagSeed] и
|
||
[CHttpCacheFilter::etagSeedExpression], может быть добавлен заголовок
|
||
«Entity Tag» (`ETag`). Заданные значения сериализуются (то есть можно использовать
|
||
как простое значение, так и массив) и, затем используются для генерации хеша
|
||
quoted base64 SHA1, который подставляется в `ETag`. Данный способ отличается от
|
||
того, что используется [Apache](http://httpd.apache.org) и другими веб-серверами.
|
||
Тем не менее, реализация в Yii полностью соответствует RFC и лучше подходит
|
||
для использования в фреймворке.
|
||
|
||
> Note|Примечание: Для соответствия [разделу 13.3.4 RFC 2616](http://tools.ietf.org/html/rfc2616#section-13.3.4),
|
||
[CHttpCacheFilter] отсылает как `ETag` *так и* `Last-Modified` когда это возможно.
|
||
Соответственно, оба заголовка будут использоваться для инвалидации кэша.
|
||
|
||
Так как `ETag` является хешем, то позволяет реализовать более сложные и точные
|
||
стратегии кеширования, чем в случае использования `Last-Modified`. К примеру, ETag
|
||
может быть инвалидирован в случае изменения темы сайта.
|
||
|
||
> Tip|Подсказка: Использование «дорогих» в плане производительности выражений
|
||
в [CHttpCacheFilter::etagSeedExpression] может свести на нет ожидаемую выгоду
|
||
от использования [CHttpCacheFilter] и даже привести к замедлению приложения потому
|
||
как используемое выражение выполняется при каждом запросе. Всегда старайтесь найти
|
||
наиболее простое выражение, показывающее факт изменения содержимого страницы.
|
||
|
||
### Влияние на SEO
|
||
|
||
Поисковые роботы обычно обращают внимание на заголовки, относящиеся к кэшированию.
|
||
Так как у некоторых из них есть ограничения на обработку определённого количества
|
||
страниц одного домена в единицу времени, то использование данной техники может
|
||
помочь индексации сайта.
|
||
|
||
|
||
<div class="revision">$Id$</div> |