Как ускорить отображение и передачу большого дерева значений в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с большими иерархическими структурами данных в управляемом приложении 1С 8.3 часто сопряжена с серьезными проблемами производительности. Ситуация, когда открытие формы выбора с «тяжелым» деревом значений занимает 10–15 секунд, является критической для пользователя. Основная причина кроется в механизмах платформы: при передаче объекта ДанныеФормыДерево между сервером и клиентом происходит глубокая сериализация всех узлов, а последующая отрисовка тысяч строк в визуальном компоненте перегружает поток интерфейса.

Разберем детально, почему это происходит и какие существуют проверенные способы оптимизации, позволяющие сократить время ожидания с секунд до миллисекунд.

Причина проблемы: Сериализация и отрисовка

Проанализируем ситуацию: когда мы помещаем дерево во временное хранилище, мы экономим только на одном этапе передачи данных. Однако при открытии второй формы платформа все равно должна:

  1. Прочитать данные из хранилища на сервере.
  2. Десериализовать их в объект ДанныеФормыДерево.
  3. Передать этот объект с сервера на клиент (полная сериализация всей структуры).
  4. Отрисовать каждый узел дерева в таблице формы.

Если дерево содержит десятки тысяч строк, именно 4-й этап становится «бутылочным горлышком». Рассмотрим эффективные стратегии решения этой задачи.

Решение 1. Использование Динамического списка

Это самый правильный архитектурный подход в 1С. ДинамическийСписок работает по принципу порционного считывания данных. Он запрашивает с сервера только те строки, которые видны пользователю на экране в данный момент (обычно 30–45 строк).

Выясним преимущества этого метода:

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

Решение 2. Табличный документ вместо дерева

Как отмечается в обсуждении, ТабличныйДокумент ведет себя иначе, чем таблица формы. Если сформировать дерево в виде табличного документа на сервере (используя группировки строк), передача этого объекта на клиент происходит быстрее. Это связано с тем, что табличный документ передается как графическое представление, и после отрисовки он не требует постоянных обращений к серверу при «схлопывании» или «разворачивании» веток (если они уже сформированы).

Рассмотрим алгоритм реализации:

  1. На сервере создаем объект ТабличныйДокумент.
  2. Обходим дерево значений, выводя области в документ и устанавливая уровни группировок через Область.Строки.Сгруппировать().
  3. Передаем готовый документ на форму.

Решение 3. Перенос дерева на отдельную вкладку (Отказ от модальности)

Вместо открытия новой формы (Форма2), мы можем разместить дерево значений непосредственно в основной форме (Форма1), но на другой странице (вкладке) панели. По умолчанию эта страница скрыта.

Разберем профит этого метода:

Пример программного переключения страниц:


&НаКлиенте
Процедура ВыбратьИсточник(Команда)
    // Переключаемся на страницу с деревом
    Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.СтраницаВыбораИсточника;
КонецПроцедуры

Решение 4. Метод «Ленивой загрузки» (Lazy Loading)

Если дерево значений невозможно заменить динамическим списком, применим метод динамической подгрузки узлов. Смысл в том, чтобы изначально загрузить в ДанныеФормыДерево только верхний уровень иерархии.

Проанализируем шаги реализации:

  1. При создании формы заполняем только первый уровень дерева.
  2. Для узлов, у которых есть дети, добавляем пустую «строку-заглушку».
  3. Используем событие таблицы ПриРазвертывании.

Пример кода для динамической подгрузки:


&НаКлиенте
Процедура СписокИсточниковПриРазвертывании(Элемент, СтрокаИдентификатор, Отказ)
    
    ТекущаяСтрока = СписокИсточников.НайтиПоИдентификатору(СтрокаИдентификатор);
    
    // Проверяем, были ли данные уже загружены
    Если ТекущаяСтрока.Подгружено = Ложь Тогда
        ЗагрузитьПодчиненныеУзлыНаСервере(СтрокаИдентификатор);
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Процедура ЗагрузитьПодчиненныеУзлыНаСервере(ИдентификаторРодителя)
    Родитель = СписокИсточников.НайтиПоИдентификатору(ИдентификаторРодителя);
    
    // Удаляем заглушку
    Заглушки = Родитель.ПолучитьЭлементы();
    Заглушки.Очистить();
    
    // Запрос к данным и заполнение реальными строками
    НоваяСтрока = Родитель.ПолучитьЭлементы().Добавить();
    НоваяСтрока.Наименование = "Реальный дочерний элемент";
    
    Родитель.Подгружено = Истина;
КонецПроцедуры

Решение 5. Кэширование формы (Singleton)

Если пользователю нужно открывать форму выбора многократно, мы можем не закрывать её, а скрывать. При повторном вызове мы проверяем, не открыта ли форма уже.

Посмотрим, как это реализовать:

Это полностью исключает повторную инициализацию дерева и его повторную отрисовку, так как объект формы живет в памяти клиента.

Итоги

Выясним, какой метод лучше выбрать: Динамический список — идеален, если данные в базе. Ленивая загрузка — лучший вариант для программно формируемых деревьев. Табличный документ — если важна сложная визуализация и группировки без частого интерактивного изменения данных. Переключение вкладок — самый быстрый способ для пользователя в рамках одного бизнес-процесса.

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

← На главную