Блог Горошко Андрея 1C-Битрикс Оптимизация Highload-блоков: Кэширование скомпилированных сущностей

Оптимизация Highload-блоков: Кэширование скомпилированных сущностей

Средний рейтинг
Еще нет оценок

При работе с HL-блоками мы постоянно пишем:

$hlblock = HL\HighloadBlockTable::getById($id)->fetch();
$entity = HL\HighloadBlockTable::compileEntity($hlblock); // <-- Здесь происходит магия
$entityClass = $entity->getDataClass();

Метод compileEntity «на лету» собирает класс сущности, анализируя пользовательские поля.

Это требует ресурсов. Если вы вызываете этот код в цикле или несколько раз в разных компонентах на одной странице, вы теряете производительность.

Паттерн: Singleton для сущностей

Лучшая практика — создать сервисный класс, который будет хранить скомпилированные классы в статическом свойстве.

namespace My\Project;

use Bitrix\Highloadblock\HighloadBlockTable;
use Bitrix\Main\Loader;

class HLBlockFactory
{
    private static $classes = [];

    /**
     * Возвращает класс сущности HL-блока по его ID или NAME
     * @param int|string $identifier ID или Название (TABLE_NAME) HL-блока
     * @return string|null Имя класса или null
     */
    public static function getClass($identifier)
    {
        if (isset(self::$classes[$identifier])) {
            return self::$classes[$identifier];
        }

        Loader::includeModule('highloadblock');

        // Пытаемся найти HL-блок
        // Если передан ID (число)
        if (is_numeric($identifier)) {
            $hlblock = HighloadBlockTable::getById($identifier)->fetch();
        } else {
            // Если передано название таблицы
            $hlblock = HighloadBlockTable::getList([
                'filter' => ['=TABLE_NAME' => $identifier]
            ])->fetch();
        }

        if (!$hlblock) {
            return null;
        }

        // Компилируем
        $entity = HighloadBlockTable::compileEntity($hlblock);
        $dataClass = $entity->getDataClass();

        // Кэшируем результат в статику
        self::$classes[$identifier] = $dataClass;
        // Можно закэшировать и по ID, и по TABLE_NAME, чтобы не искать второй раз
        self::$classes[$hlblock['ID']] = $dataClass;
        self::$classes[$hlblock['TABLE_NAME']] = $dataClass;

        return $dataClass;
    }
}

Как использовать

use My\Project\HLBlockFactory;

// Первый вызов: будет запрос к БД и компиляция
$brandClass = HLBlockFactory::getClass('b_brands'); 
$brands = $brandClass::getList([])->fetchAll();

// ... где-то в другом компоненте ...

// Второй вызов: вернется мгновенно из статического массива
$brandClass = HLBlockFactory::getClass('b_brands');

Вывод:
Избегайте дублирования вызовов compileEntity в рамках одного хита.

Использование простой фабрики-обертки сделает ваш код чище и быстрее, особенно на страницах с большим количеством компонентов.

compileEntity кэширование, HighloadBlockTable::compileEntity, оптимизация HL-блоков, HLblock производительность, getTable.

Мой рейтинг:

Добавить комментарий

Related Post

1с Битрикс фильтрация по свойству элементов1с Битрикс фильтрация по свойству элементов

Средний рейтинг Еще нет оценок В Битриксе вы можете использовать различные условия выборки с помощью фильтрации в параметре 'filter' при вызове метода getList() или других методов выборки данных. Вот несколько

Продвинутое кэширование в Битрикс: Managed Cache и Tagged CacheПродвинутое кэширование в Битрикс: Managed Cache и Tagged Cache

Средний рейтинг Еще нет оценок Обычное кэширование по времени (CPHPCache, Bitrix\Main\Data\Cache) отлично работает, но у него есть недостаток: если данные изменились, кэш обновится только по истечении своего TTL (времени жизни). Пользователи будут видеть

Создание своей ORM-сущности в Битрикс: DataManager и getMap с нуляСоздание своей ORM-сущности в Битрикс: DataManager и getMap с нуля

Средний рейтинг Еще нет оценок D7 ORM позволяет работать не только со стандартными сущностями (ElementTable, UserTable), но и описывать свои собственные для любых таблиц в базе данных. Это позволяет получить все преимущества