Кэширование фрагментов в Yii 2
Кэширование фрагментов в Yii 2

Кэширование фрагментов

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

Старт! Честный VDS/VPS, на котором «Лунная База» живет уже 20+ лет

Задумываетесь о том, чтобы поднять свой pet-проект, сайт клиента или настроить окружение для разработки? Уже пора подумать, где арендовать железо.

Лунная База хостится на FirstVDS более 20 лет. Мыслей о том, чтобы перебраться на другой хостинг, не было ни разу (хотя опыт работы с другими вариантами, конечно, есть).

Бывали разные ситуации, но они бывают на любом железе. Главное, что нужно понять: здесь нет маркетинговой шелухи и сказок про «мы всё сделаем за вас». Если вы берете VDS — вам дают полный root, возможность накатить любую ОС и не лезут в ваши конфиги.

Если в саппорт написать с вопросом по вашему коду и получить ответ: «Читайте документацию и разбирайтесь сами» или «Обратитесь к профильному специалисту» — это не повод обижаться. Это повод углубить свои знания в DevOps и сайтостроении! Бегите от тех, кто пообещает: «Мы всё чиним и настраиваем абсолютно бесплатно!». Никто никогда не работает «по доброте душевной» в ущерб себе, а бесплатный сыр в администрировании обычно заканчивается сломанной базой данных.

Что по факту: Гибкое масштабирование ядер и RAM, экономия по сравнению с физическими серверами и адекватная панель ispmanager, если она вам нужна.



Для кэширования фрагментов используйте следующий код в представлении:

if ($this->beginCache($id)) {

    // ... здесь создаём содержимое ...

    $this->endCache();
}

Таким образом заключите то, что вы хотите закэшировать между вызовом [[yii\base\View::beginCache()|beginCache()]] и [[yii\base\View::endCache()|endCache()]]. Если содержимое будет найдено в кэше, [[yii\base\View::beginCache()|beginCache()]] отобразит закэшированное содержимое и вернёт false, минуя генерацию содержимого. В противном случае, будет выполнен код генерации контента и когда будет вызван [[yii\base\View::endCache()|endCache()]], то сгенерированное содержимое будет записано и сохранено в кэше.

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

Параметры кэширования

Вызывая метод [[yii\base\View::beginCache()|beginCache()]], мы можем передать в качестве второго аргумента массив, содержащий параметры кэширования для управления кэшированием фрагмента. Заглядывая за кулисы, можно увидеть, что этот массив будет использоваться для настройки виджета [[yii\widgets\FragmentCache]], который реализует фактическое кэширование фрагментов.

Срок хранения

Наверное, наиболее часто используемым параметром является [[yii\widgets\FragmentCache::duration|duration]]. Он определяет какое количество секунд содержимое будет оставаться действительным (корректным). Следующий код помещает фрагмент в кэш не более, чем на час:

if ($this->beginCache($id, ['duration' => 3600])) {

    // ... здесь создаём содержимое ...

    $this->endCache();
}

Если мы не установим длительность (срок хранения), она будет равна значению по умолчанию (60 секунд). Это значит, что кэшированное содержимое станет недействительным через 60 секунд.

Зависимости

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

Для определения зависимости мы устанавливаем параметр [[yii\widgets\FragmentCache::dependency|dependency]], который может быть либо объектом [[yii\caching\Dependency]], либо массивом настроек, который может быть использован для создания объекта [[yii\caching\Dependency]]. Следующий код определяет содержимое фрагмента, зависящее от изменения значения столбца updated_at:

$dependency = [
    'class' => 'yii\caching\DbDependency',
    'sql' => 'SELECT MAX(updated_at) FROM post',
];

if ($this->beginCache($id, ['dependency' => $dependency])) {

    // ... здесь создаём содержимое ...

    $this->endCache();
}

Вариации

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

Чтобы задать вариации кэша, установите параметр [[yii\widgets\FragmentCache::variations|variations]], который должен быть массивом, содержащим скалярные значения, каждое из которых представляет определенный коэффициент вариации. Например, чтобы кэшировать содержимое в зависимости от языка приложения, вы можете использовать следующий код:

if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {

    // ... здесь создаём содержимое ...

    $this->endCache();
}

Переключение кэширования

Иногда может потребоваться включать кэширование фрагментов только для определённых условий. Например, страницу с формой мы хотим кэшировать только тогда, когда обращение к ней произошло впервые (посредством GET запроса). Любое последующее отображение формы (посредством POST запроса) не должно быть кэшировано, потому что может содержать данные, введённые пользователем. Для этого мы задаём параметр [[yii\widgets\FragmentCache::enabled|enabled]]:

if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {

    // ... здесь создаём содержимое ...

    $this->endCache();
}

Вложенное кэширование

Кэширование фрагментов может быть вложенным. Это значит, что кэшируемый фрагмент окружён более крупным фрагментом (содержится в нём), который также кэшируется. Например, комментарии кэшируются во внутреннем фрагменте кэша, и они же кэшируются вместе с содержимым сообщения во внешнем фрагменте кэша. Следующий код демонстрирует как два фрагмента кэша могут быть вложенными:

if ($this->beginCache($id1)) {

    // ...логика создания контента...

    if ($this->beginCache($id2, $options2)) {

        // ...логика создания контента...

        $this->endCache();
    }

    // ...логика создания контента...

    $this->endCache();
}

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

Динамическое содержимое

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

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

Вы можете вызвать [[yii\base\View::renderDynamic()]] в пределах кэширования фрагмента для вставки динамического содержимого в нужное место, как в примере ниже:

if ($this->beginCache($id1)) {

    // ...логика создания контента...

    echo $this->renderDynamic('return Yii::$app->user->identity->name;');

    // ...логика создания контента...

    $this->endCache();
}

Метод [[yii\base\View::renderDynamic()|renderDynamic()]] принимает некоторую часть PHP кода как параметр. Возвращаемое значение этого кода будет вставлено в динамическое содержимое. Этот PHP код будет выполняться для каждого запроса, независимо от того находится ли он внутри кэширования фрагмента или нет.

Самый честный хостинг за 20+ лет существования Лунной Базы

Задумываешься о том, чтобы поднять свой сайт в Интернете? Уже пора подумать о том, какой хостинг выбрать?

Лунная База хостится 20+ лет на firstDVS. При этом, мыслей о том, чтобы перебраться на другой хостинг не было. (Но, при этом есть опыт работы с другими вариантами.)

Бывали с firstDVS разные ситуации, но, они бывают на всех хостингах. Единственное, что тут важно понять, - это то, что никто ничего тебе не будет впаривать... Но, и работать за тебя тоже никто не станет. Если в саппорт ответили: «Читайте по ссылке и разбирайтесь сами...» или вообще «Обратитесь за помощью к специалисту», - это повод углубить свои знания в области сайтостроения, а не бежать к тем, что пообещают: «Мы всё чиним и всё делаем за своих клиентов абсолютно бесплатно!» Никто никогда ничего ни за кого "по доброте душевной" не делал, не делает и не будет делать!

Старт! Горячий старт на просторы интернета
Старт! Горячий старт на просторы интернета
Старт! Меню