Отложенный ресайз облачных файлов в CFile::ResizeImageGet

08.04.2026

Проблема/контекст

У CFile::ResizeImageGet() есть шестой параметр $bImmediate, но по коду ядра он не включает "отложенный ресайз" сам по себе. В main/classes/general/file.php метод только передает этот флаг в событие OnBeforeResizeImage, а реальная delayed-логика подключается обработчиком модуля clouds.

Это важно, потому что для локальных файлов ресайз остается синхронным, а для файлов с HANDLER_ID из облачного хранилища поведение меняется. В CCloudStorage::OnBeforeResizeImage() ядро проверяет опцию clouds.delayed_resize и при $bImmediate = false не строит миниатюру сразу, а ставит задачу в таблицу b_clouds_file_resize через ResizeImageFileDelay(). Затем CCloudStorage::OnBeforeProlog() перехватывает запрос к resize_cache, вызывает ResizeImageFileCheck() и уже после генерации перенаправляет на готовый файл в бакете.

Решение с кодом

Практическое правило простое: delayed-режим подходит для публичных списков, где допустим отдельный HTTP-запрос на первую генерацию картинки. Для AJAX-ответов, модальных превью, административных форм и мест, где URL должен вести на уже существующий файл, ставьте $bImmediate = true. Сам Bitrix следует этому же правилу: в Bitrix\Main\UI\FileInputUnclouder::exec() и шаблоне main.file.input превью строится через ResizeImageGet(..., true).

        <?php
declare(strict_types=1);

/**
 * Для cloud-файлов решаем, можно ли отложить генерацию.
 */
function getPreviewImage(array $file, int $width, int $height, bool $needImmediate): array
{
    $result = \CFile::ResizeImageGet(
        $file,
        ['width' => $width, 'height' => $height],
        bInitSizes: true,   // вернуть реальные размеры результата
        bImmediate: $needImmediate
    );

    return is_array($result) ? $result : [];
}

$file = \CFile::GetFileArray($pictureId);
$isCloudFile = (int)($file['HANDLER_ID'] ?? 0) > 0;

// В списке товаров допускаем delayed-генерацию только для cloud-файлов.
$listImage = getPreviewImage($file, 320, 320, false);

// В AJAX-превью файл нужен сразу, иначе можно получить URL на еще не созданный объект.
$modalImage = getPreviewImage($file, 1200, 1200, $isCloudFile);

    

Если вы вызываете ResizeImageGet() в JSON-ответе или сразу вставляете src в интерфейс, не рассчитывайте, что delayed-режим успеет создать файл к этому же ответу. Документация показывает только прямой CFile::ResizeImage() после SaveFile(), но не объясняет этот разрыв между локальным и cloud-сценарием. Поэтому проверяйте HANDLER_ID и осознанно выбирайте режим генерации, а не передавайте шестой параметр "на всякий случай".

Есть и еще один нюанс, который виден только в исходниках clouds. Метод ResizeImageFileDelay() не ставит задачу без необходимости: если Rectangle::resize() показывает, что новое изображение не требуется и нет фильтров или watermark, delayed-сценарий не включается. А если задача уже падала, ядро пытается перезапустить ее только спустя пять минут по TIMESTAMP_X. Это означает, что delayed-режим полезен именно как фоновая оптимизация выдачи, а не как гарантия мгновенного результата при повторном запросе.

Итог

$bImmediate имеет практический смысл только в связке с облачным хранилищем и clouds.delayed_resize. Для интерактивных превью включайте немедленную генерацию, для публичных страниц можно оставлять delayed-режим.

Опубликовано 4 дня назад

Комментарии (0)

Пожалуйста, войдите в аккаунт, чтобы оставить комментарий

Оставить комментарий

Пока нет ни одного комментария. Будьте первым!

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

AI Домовой История

0 / 25

Привет! Я помогу с вопросами по 1С-Битрикс.

Спрашивай про D7, ORM, компоненты или события.

Требуется авторизация

Войдите или зарегистрируйтесь, чтобы задавать вопросы AI-ассистенту.

Войти