Работа с большими иерархическими структурами данных в управляемом приложении 1С 8.3 часто сопряжена с серьезными проблемами производительности. Ситуация, когда открытие формы выбора с «тяжелым» деревом значений занимает 10–15 секунд, является критической для пользователя. Основная причина кроется в механизмах платформы: при передаче объекта ДанныеФормыДерево между сервером и клиентом происходит глубокая сериализация всех узлов, а последующая отрисовка тысяч строк в визуальном компоненте перегружает поток интерфейса.
Разберем детально, почему это происходит и какие существуют проверенные способы оптимизации, позволяющие сократить время ожидания с секунд до миллисекунд.
Проанализируем ситуацию: когда мы помещаем дерево во временное хранилище, мы экономим только на одном этапе передачи данных. Однако при открытии второй формы платформа все равно должна:
ДанныеФормыДерево.Если дерево содержит десятки тысяч строк, именно 4-й этап становится «бутылочным горлышком». Рассмотрим эффективные стратегии решения этой задачи.
Это самый правильный архитектурный подход в 1С. ДинамическийСписок работает по принципу порционного считывания данных. Он запрашивает с сервера только те строки, которые видны пользователю на экране в данный момент (обычно 30–45 строк).
Выясним преимущества этого метода:
Если же данные для дерева формируются программно (сложным расчетом), их можно предварительно записать во временную таблицу (или реальную служебную таблицу) и отобразить через ДинамическийСписок с произвольным запросом.
Как отмечается в обсуждении, ТабличныйДокумент ведет себя иначе, чем таблица формы. Если сформировать дерево в виде табличного документа на сервере (используя группировки строк), передача этого объекта на клиент происходит быстрее. Это связано с тем, что табличный документ передается как графическое представление, и после отрисовки он не требует постоянных обращений к серверу при «схлопывании» или «разворачивании» веток (если они уже сформированы).
Рассмотрим алгоритм реализации:
ТабличныйДокумент.Область.Строки.Сгруппировать().Вместо открытия новой формы (Форма2), мы можем разместить дерево значений непосредственно в основной форме (Форма1), но на другой странице (вкладке) панели. По умолчанию эта страница скрыта.
Разберем профит этого метода:
ВременноеХранилище для передачи данных между формами.Пример программного переключения страниц:
&НаКлиенте
Процедура ВыбратьИсточник(Команда)
// Переключаемся на страницу с деревом
Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.СтраницаВыбораИсточника;
КонецПроцедуры
Если дерево значений невозможно заменить динамическим списком, применим метод динамической подгрузки узлов. Смысл в том, чтобы изначально загрузить в ДанныеФормыДерево только верхний уровень иерархии.
Проанализируем шаги реализации:
ПриРазвертывании.Пример кода для динамической подгрузки:
&НаКлиенте
Процедура СписокИсточниковПриРазвертывании(Элемент, СтрокаИдентификатор, Отказ)
ТекущаяСтрока = СписокИсточников.НайтиПоИдентификатору(СтрокаИдентификатор);
// Проверяем, были ли данные уже загружены
Если ТекущаяСтрока.Подгружено = Ложь Тогда
ЗагрузитьПодчиненныеУзлыНаСервере(СтрокаИдентификатор);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ЗагрузитьПодчиненныеУзлыНаСервере(ИдентификаторРодителя)
Родитель = СписокИсточников.НайтиПоИдентификатору(ИдентификаторРодителя);
// Удаляем заглушку
Заглушки = Родитель.ПолучитьЭлементы();
Заглушки.Очистить();
// Запрос к данным и заполнение реальными строками
НоваяСтрока = Родитель.ПолучитьЭлементы().Добавить();
НоваяСтрока.Наименование = "Реальный дочерний элемент";
Родитель.Подгружено = Истина;
КонецПроцедуры
Если пользователю нужно открывать форму выбора многократно, мы можем не закрывать её, а скрывать. При повторном вызове мы проверяем, не открыта ли форма уже.
Посмотрим, как это реализовать:
ПередЗакрытием ставим Отказ = Истина и просто делаем форму невидимой: ЭтаФорма.Видимость = Ложь.Истина и активизируем.Это полностью исключает повторную инициализацию дерева и его повторную отрисовку, так как объект формы живет в памяти клиента.
Выясним, какой метод лучше выбрать: Динамический список — идеален, если данные в базе. Ленивая загрузка — лучший вариант для программно формируемых деревьев. Табличный документ — если важна сложная визуализация и группировки без частого интерактивного изменения данных. Переключение вкладок — самый быстрый способ для пользователя в рамках одного бизнес-процесса.
Применение любого из этих методов позволит сократить время отклика интерфейса с 11 секунд до долей секунды, что существенно повысит комфорт работы пользователей.