Как ускорить вывод большого количества записей в Дерево Значений на Управляемой Форме?

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

При разработке сложных интерфейсов подбора товаров или документов мы часто сталкиваемся с необходимостью отобразить пользователю иерархический список. Стандартное решение — использовать ДеревоЗначений. Однако, когда количество записей превышает несколько тысяч (в рассмотренном случае — более 200 000), производительность падает катастрофически. Запрос может выполняться быстро, но передача данных с сервера на клиент и отрисовка формы занимают десятки секунд.

Давайте подробно разберем, почему это происходит, и проанализируем эффективные методы оптимизации, собранные из опыта сообщества разработчиков 1С.

Почему тормозит Дерево Значений?

Прежде чем приступать к лечению, давайте поставим диагноз. В описанной ситуации запрос выполняется 7 секунд, а "вывод формы" — 65 секунд. Это классическая проблема "толстого" канала между сервером и клиентом в управляемых формах.

Основные причины замедления:

  1. Сериализация данных: Платформа должна преобразовать ДеревоЗначений (серверный объект) в ДанныеФормыДерево (обект, доступный на клиенте). Это ресурсоемкая операция при большом объеме строк.
  2. Передача ссылочных типов: Если в колонках дерева находятся ссылки (например, СправочникСсылка.Номенклатура), то при отрисовке на клиенте платформа пытается получить их текстовое представление. Если представления не закэшированы, это вызывает множество неявных обращений к серверу или базе данных.
  3. Отрисовка в браузере/клиенте: Создание DOM-элементов для 200 000 строк требует огромного объема оперативной памяти клиентской машины и времени процессора.

Стратегия 1: Оптимизация типов данных в запросе

Самый быстрый способ получить прирост производительности (в обсуждении упоминается ускорение до 70%) — отказаться от передачи ссылочных типов на клиент, если они нужны только для отображения.

При передаче ссылки тратит время на то, чтобы превратить Уникальный Идентификатор в понятную строку (например, "Болт М6"). Мы можем сделать это сами на этапе запроса.

Как это реализовать:

Вместо выборки поля Ссылка, используйте функцию языка запросов ПРЕДСТАВЛЕНИЕ().


ВЫБРАТЬ
    ПРЕДСТАВЛЕНИЕ(Номенклатура.Ссылка) КАК ТоварПредставление,
    Номенклатура.Артикул,
    Номенклатура.УникальныйИдентификатор КАК Идентификатор -- Строка, если нужно для связи
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Важные нюансы:

Стратегия 2: Ограничение выборки (Паттерн "Первые 100")

Зададим себе вопрос: способен ли человек воспринять и проанализировать список из 200 000 строк? Ответ очевиден — нет. Пользователь все равно будет пользоваться поиском или отборами.

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

Алгоритм действий:

  1. В запросе всегда используйте конструкцию ПЕРВЫЕ.
  2. Выводите пользователю сообщение: "Показаны первые 100 записей. Пожалуйста, уточните критерии поиска".
  3. Пусть пользователь вводит фильтры (по наименованию, артикулу, родителю), и только тогда вы перезаполняете дерево.

ВЫБРАТЬ ПЕРВЫЕ 100
    Номенклатура.Ссылка,
    Номенклатура.Наименование
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Наименование ПОДОБНО &СтрокаПоиска

Это кардинально снижает нагрузку на канал связи и мгновенно отрисовывает форму.

Стратегия 3: Использование Динамического списка

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

Проблема с чекбоксами (Множественный выбор):

В теме справедливо заметили, что в динамическом списке нет встроенной колонки "Пометка" (Checkboxes), так как список виртуален. Однако это решаемая задача.

Решение для чекбоксов в Динамическом списке:

  1. Добавьте на форму реквизит СписокВыбранныхЭлементов (тип СписокЗначений или Массив).
  2. В событии динамического списка (например, двойной клик или специальная кнопка "Выбрать") добавляйте текущий идентификатор в этот массив.
  3. Используйте УсловноеОформление формы: если ссылка текущей строки содержится в СписокВыбранныхЭлементов, окрашивайте строку цветом или меняйте картинку строки на "галочку".

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

Стратегия 4: "Ленивая" загрузка дерева (Lazy Loading)

Если вам критически важно сохранить именно ДеревоЗначений с иерархией, используйте поэтапную загрузку. Не стройте всё дерево сразу.

Реализация:

  1. При открытии формы загружайте только корни (элементы первого уровня иерархии).
  2. Каждому узлу программно проставьте признак того, что у него есть подчиненные элементы (даже если их пока нет в коллекции формы). Это нужно, чтобы появился "крестик" раскрытия.
  3. Используйте событие элемента формы ПередРазворачиванием (BeforeExpand).
  4. В обработчике этого события идите на сервер, выполняйте запрос только по подчиненным элементам для текущего узла и добавляйте их в дерево.

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

КонецПроцедуры

Этот метод обеспечивает мгновенное открытие формы, так как объем передаваемых данных минимален.

Резюме

Давайте подведем итог. Попытка вывести 200 000 строк в дерево на клиенте — это тупиковый путь. Для решения задачи оптимизации следует выбрать один из следующих подходов:

  1. Ограничение выборки: Показывать только первые N записей и требовать от пользователя использования фильтров. Это самое простое и эффективное решение.
  2. Оптимизация данных: Преобразовывать ссылки в строки (представления) прямо в запросе, чтобы избежать лишних обращений к БД при отрисовке.
  3. Динамический список: Использовать штатный механизм платформы, эмулируя галочки через отдельный массив выбранных значений.
  4. Ленивая загрузка: Подгружать ветки дерева только в момент нажатия пользователем на "плюсик".

Комбинируя эти методы, вы сможете сократить время открытия формы с 65 секунд до долей секунды.

← На главную