При разработке сложных интерфейсов подбора товаров или документов мы часто сталкиваемся с необходимостью отобразить пользователю иерархический список. Стандартное решение — использовать ДеревоЗначений. Однако, когда количество записей превышает несколько тысяч (в рассмотренном случае — более 200 000), производительность падает катастрофически. Запрос может выполняться быстро, но передача данных с сервера на клиент и отрисовка формы занимают десятки секунд.
Давайте подробно разберем, почему это происходит, и проанализируем эффективные методы оптимизации, собранные из опыта сообщества разработчиков 1С.
Прежде чем приступать к лечению, давайте поставим диагноз. В описанной ситуации запрос выполняется 7 секунд, а "вывод формы" — 65 секунд. Это классическая проблема "толстого" канала между сервером и клиентом в управляемых формах.
Основные причины замедления:
ДеревоЗначений (серверный объект) в ДанныеФормыДерево (обект, доступный на клиенте). Это ресурсоемкая операция при большом объеме строк.СправочникСсылка.Номенклатура), то при отрисовке на клиенте платформа пытается получить их текстовое представление. Если представления не закэшированы, это вызывает множество неявных обращений к серверу или базе данных.Самый быстрый способ получить прирост производительности (в обсуждении упоминается ускорение до 70%) — отказаться от передачи ссылочных типов на клиент, если они нужны только для отображения.
При передаче ссылки 1С тратит время на то, чтобы превратить Уникальный Идентификатор в понятную строку (например, "Болт М6"). Мы можем сделать это сами на этапе запроса.
Как это реализовать:
Вместо выборки поля Ссылка, используйте функцию языка запросов ПРЕДСТАВЛЕНИЕ().
ВЫБРАТЬ
ПРЕДСТАВЛЕНИЕ(Номенклатура.Ссылка) КАК ТоварПредставление,
Номенклатура.Артикул,
Номенклатура.УникальныйИдентификатор КАК Идентификатор -- Строка, если нужно для связи
ИЗ
Справочник.Номенклатура КАК Номенклатура
Важные нюансы:
ПоместитьВоВременноеХранилище, а в дереве храните только идентификатор (UUID).Зададим себе вопрос: способен ли человек воспринять и проанализировать список из 200 000 строк? Ответ очевиден — нет. Пользователь все равно будет пользоваться поиском или отборами.
Поэтому одним из самых разумных архитектурных решений является принудительное ограничение выборки.
Алгоритм действий:
ПЕРВЫЕ.
ВЫБРАТЬ ПЕРВЫЕ 100
Номенклатура.Ссылка,
Номенклатура.Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Наименование ПОДОБНО &СтрокаПоиска
Это кардинально снижает нагрузку на канал связи и мгновенно отрисовывает форму.
Если данные хранятся в базе (а не в таблице значений), лучшим инструментом является ДинамическийСписок. Он разработан специально для таких задач: считывает данные порциями по мере прокрутки.
Проблема с чекбоксами (Множественный выбор):
В теме справедливо заметили, что в динамическом списке нет встроенной колонки "Пометка" (Checkboxes), так как список виртуален. Однако это решаемая задача.
Решение для чекбоксов в Динамическом списке:
СписокВыбранныхЭлементов (тип СписокЗначений или Массив).УсловноеОформление формы: если ссылка текущей строки содержится в СписокВыбранныхЭлементов, окрашивайте строку цветом или меняйте картинку строки на "галочку".Такой подход работает намного быстрее, чем попытка загрузить все данные в дерево только ради галочек.
Если вам критически важно сохранить именно ДеревоЗначений с иерархией, используйте поэтапную загрузку. Не стройте всё дерево сразу.
Реализация:
ПередРазворачиванием (BeforeExpand).
&НаКлиенте
Процедура ДеревоПередРазворачиванием(Элемент, Строка, Отказ)
ТекущаяСтрока = Дерево.НайтиПоИдентификатору(Строка);
Если ТекущаяСтрока.ПолучитьЭлементы().Количество() = 0 Тогда
// Загружаем данные только сейчас
ЗагрузитьПодчиненныеЭлементыНаСервере(ТекущаяСтрока);
КонецЕсли;
КонецПроцедуры
Этот метод обеспечивает мгновенное открытие формы, так как объем передаваемых данных минимален.
Давайте подведем итог. Попытка вывести 200 000 строк в дерево на клиенте — это тупиковый путь. Для решения задачи оптимизации следует выбрать один из следующих подходов:
Комбинируя эти методы, вы сможете сократить время открытия формы с 65 секунд до долей секунды.