Дата последнего изменения: 15.11.2023
Рассмотрим примеры, как можно улучшить производительность проекта.
Кеш очень важная составляющая производительности проектов. Чем эффективнее кешируем, чем кеш легче и быстрее, тем меньше ресурсов надо на поддержание проекта.
Но работа кеша может быть организована не совсем корректно, что приводит к проблемам производительности.Как неправильно:
// Класс кеширования пользователя с некорретным кешированием class User { private $userData; function __construct($userId = false) { if (!$userId) { global $USER; $userId = $USER->GetID(); } $cntStartCacheId = __CLASS__.'::'.__FUNCTION__.'|'.SITE_ID.'|'.$userId; $cache = new \CXxxCache($cntStartCacheId.'sid0',3600,'user_data'); $this->userData = $cache->Init(); if (null == $this->userData) { $this->putUserData(array("ID"=>$userId)); $this->putUserData(\CUser::GetByID($userId)->Fetch()); $this->putUserData(array("DEPARTMENT" => $this->getDepartment())); $cache->registerTag('USER_NAME_'.$userId); $cache->set($this->userData); } } }Что не так в примере выше:
GetByID
Fetch
Как правильно:
class User { private $userData; function __construct($userId = false) { if (!$userId) { global $USER; $userId = $USER->GetID(); } $cntStartCacheId = __CLASS__.'::'.__FUNCTION__.'|'.SITE_ID.'|'.$userId; $cache = new \CXxxCache( $cntStartCacheId.'sid0', // увеличили время кеширования 604800, // путь для ключей кеша сделали зависимым от $userID 'user_data/'.substr(md5($userId),2,2).'/'.$userId ); $this->userData = $cache->Init(); if (null == $this->userData) { $this->putUserData(array("ID"=>$userId)); // Выбираем только нужные поля $this->putUserData(\CUser::GetList(...)->GetNext(true, false)); $this->putUserData(array("DEPARTMENT" => $this->getDepartment())); $cache->registerTag('USER_NAME_'.$userId); $cache->set($this->userData); } } }
GetByID
на
GetList
Достаточно часто в проектах многие используют вызов CIBlockElement::GetById. Простой, удобный метод, когда надо вытащить какое-то поле для элемента инфоблока. Но этот метод тянет все поля и все свойства элемента. В случае инфоблока с большим количеством свойств и большого числа посетителей на сайте этот простой запрос приводит к снижению производительности.Fetch
на GetNext(true, false)
.Пример на компоненте, который отображает дни рождения. Установлено большое время кеширования и добавлен дополнительный параметр, который сам компонент никак не отрабатывает и его не обрабатывает шаблон. Но так как в параметры подставлен date
, то в 0 часов получим новый ключ у кеша данного компонента.
IncludeComponent( "bitrix:intranet.structure.birthday.nearest", "widget", Array( "CACHE_TYPE" => "A", "CACHE_TIME" => "86450", "DATE_FORMAT" => "j F", "DETAIL_URL" => "#SITE_DIR#company/personal/user/#USER_ID#/", "DEPARTMENT" => "0", ..... "CACHE_DATE" => date('dmy') ) );
В таком случае часто проставляют лишние параметры, что приводит к увеличению кеша. (например date без параметров приводит к обновлению кеша каждую секунду).
<?php // Пример добавление в ключ кеша метки времени для корректного переключения кеша. Метка может быть и не из времени. $cache = Bitrix\Main\Data\Cache::createInstance(); if ($cache->initCache(86450, '/some_key/'.date('myd').'/', '/some_dir/')) { $var = $cache->getVars(); } else { // Получение данных $cache->startDataCache(); $cache->endDataCache($var); }
Процесс импорта обычно приводит к сбросу кеша. Если мы выгружаем большой объем данных - это занимает продолжительное время и дает большую нагрузку на боевом проекте. В ряде случаев этого можно избежать. В частности при работе с инфоблоками:
Индексация фасетного индекса также может быть отложена (т.е. отключена перед импортом и включена по окончании).
<?php // Отключение сброса тегированного кеша инфоблоков и пересчета фасетного индекса, во время импорта. Bitrix\Iblock\PropertyIndex\Manager::enableDeferredIndexing(); Bitrix\Catalog\Product\Sku::enableDeferredCalculation(); \CAllIBlock::disableTagCache($iblockID); // Импорт элементов \CAllIBlock::enableTagCache($iblockID); \CAllIBlock::clearIblockTagCache($iblockID); Bitrix\Catalog\Product\Sku::disableDeferredCalculation(); Bitrix\Catalog\Product\Sku::calculate(); Bitrix\Iblock\PropertyIndex\Manager::disableDeferredIndexing(); Bitrix\Iblock\PropertyIndex\Manager::runDeferredIndexing($iblockID);
Т.о. улучшение производительности достигается обновлением индексов и кеша только один раз, а не по количеству элементов.
|
if(defined('BX_COMP_MANAGED_CACHE')) $GLOBALS['CACHE_MANAGER']->ClearByTag('iblock_id_'.$arParams['IBLOCK_ID']);