Почему возникают задержки при изменении видимости элементов на управляемой форме 1С и как это исправить?

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

Разработка сложных интерфейсов в среде 1С:Предприятие 8.3 на управляемых формах часто преподносит неприятные сюрпризы в виде низкой производительности. Одной из классических проблем является возникновение «фризов» или задержек (от 2 до 6 секунд) при программном изменении свойства Видимость элементов формы. Особенно остро эта проблема проявляется в клиент-серверном варианте работы, в то время как на файловой базе всё может работать мгновенно. Рассмотрим причины этого поведения и разберем эффективные методы решения.

Анализ проблемы: почему свойство Видимость вызывает тормоза?

Для начала проанализируем ситуацию: на форме АРМ (автоматизированного рабочего места) расположено несколько динамических списков и множество кнопок. При выборе строки в таблице программа должна показать только актуальные команды в контекстном меню. Программист меняет свойство Видимость для десятка элементов, и форма «замирает».

Выясним причину такого поведения платформы. В управляемом приложении за отрисовку интерфейса отвечает клиентское приложение, но логика компоновки (Layout) элементов находится на стороне сервера. Когда мы изменяем свойство Видимость, платформа выполняет следующие действия:

  1. Неявный контекстный серверный вызов: Изменение видимости (в отличие от доступности) часто требует пересчета всей геометрии формы. Платформа должна решить, как «схлопнуть» пустое место или куда раздвинуть соседние элементы.
  2. Синхронизация данных: При любом серверном вызове (даже неявном) платформа пытается синхронизировать состояние всех объектов на форме. Если на форме есть тяжелые динамические списки, они могут инициировать обновление своих данных или повторное выполнение запросов к БД.
  3. Перестроение дерева элементов: Сервер формирует новую XML-структуру формы и передает ее клиенту. На сложной форме этот пакет данных может быть весьма объемным, а процесс его обработки — длительным.

Важно отметить, что в старых версиях платформы (до 8.3.15, включая популярную 8.3.10) механизмы оптимизации отрисовки работали слабее, и почти каждое изменение видимости приводило к полноценному серверному вызову.

Способ 1. Использование свойства Доступность вместо Видимости

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

Однако этот способ имеет эстетический недостаток: неактивные кнопки продолжают занимать место, загромождая интерфейс. Если это критично для пользователя, перейдем к более сложным методам.

Способ 2. Оптимизация через изменение состава элементов

Рассмотрим решение, которое применил автор темы после долгих тестов. Вместо того чтобы управлять видимостью десяти различных кнопок, мы можем создать фиксированное количество элементов (например, 4 универсальные кнопки) и менять их внутренние свойства, которые не влияют на Layout формы.

Разберем, как это реализовать. Вместо кода:


Элементы.КнопкаСоздать.Видимость = Ложь;
Элементы.КнопкаУдалить.Видимость = Истина;

Мы используем изменение заголовка, картинки и действия. Посмотрим на пример реализации логики в событии Выбор или ПриАктивизацииСтроки:


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

    // Вместо Видимости меняем только наполнение существующих кнопок
    Если ЗначениеЗаполнено(ТекущиеДанные.ЗаписьНаПрием) Тогда
        Элементы.КонтекстноеМеню_Кнопка1.Заголовок = "Просмотреть прием";
        Элементы.КонтекстноеМеню_Кнопка1.ИмяКоманды = "КомандаПросмотреть";
    Иначе
        Элементы.КонтекстноеМеню_Кнопка1.Заголовок = "Создать запись";
        Элементы.КонтекстноеМеню_Кнопка1.ИмяКоманды = "КомандаСоздать";
    КонецЕсли;

    // Вызов меню через эмуляцию клавиш (если требуется)
    Скрипт = Новый COMОбъект("WScript.Shell");
    Скрипт.SendKeys("+{F10}");
КонецПроцедуры

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

Способ 3. Диагностика неявных вызовов через Технологический журнал

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

Настройте сбор события CALL. В логах вы увидите событие ContextCall в момент изменения видимости. Если время выполнения этого события совпадает с длительностью «фриза», значит, гипотеза о серверном пересчете формы подтверждена. Также обратите внимание на количество данных, передаваемых между сервером и клиентом.

Способ 4. Оптимизация динамических списков

Часто «тормозит» не сама видимость, а побочный эффект в виде обновления динамических списков. Проанализируем настройки ваших списков на форме:

Способ 5. Альтернативные подходы к реализации меню

Если стандартное контекстное меню продолжает работать медленно, рассмотрим более радикальные, но эффективные способы:

  1. Использование всплывающих форм: Вместо контекстного меню можно разработать маленькую вспомогательную управляемую форму. Она вызывается методом ОткрытьФорму() в координатах курсора. Поскольку это отдельный объект, открытие такой формы не вызывает пересчета основной тяжелой формы АРМ.
  2. Группы страниц: Если нужно скрыть/показать большой блок элементов, попробуйте поместить их на разные страницы группы типа «Страницы» и менять свойство ТекущаяСтраница. Это работает быстрее, чем перебор видимости каждого элемента в отдельности.
  3. Функциональные опции: Если видимость элементов зависит не от данных в строке, а от прав или настроек системы, используйте механизм функциональных опций. Они кэшируются платформой и работают значительно оптимальнее ручного управления видимостью.

Резюме

Подведем итог. Чтобы избавиться от тормозов при изменении видимости, выполните следующие шаги:

  1. Попробуйте заменить Видимость на Доступность.
  2. Если нужно именно скрывать элементы, минимизируйте количество обращений к свойству Видимость. Лучше один раз скрыть целую группу, чем 10 отдельных кнопок.
  3. Рассмотрите вариант с динамическим изменением Заголовков и Команд у ограниченного набора кнопок.
  4. Проверьте версию платформы. Обновление до 8.3.15+ может значительно улучшить ситуацию за счет оптимизации клиентской отрисовки.

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

← На главную