Почему форма в веб-клиенте 1С долго открывается при программной установке видимости колонок табличной части?

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

При разработке управляемого интерфейса в 1С разработчики нередко сталкиваются с ситуацией, когда форма документа, справочника или бизнес-процесса в тонком клиенте открывается мгновенно, а в веб-клиенте зависает на десятки секунд. Часто источником проблемы кажется безобидная строка установки видимости элемента формы, например: Элементы.ОплатыЗаказПоставщику.Видимость = Истина;. Разберем по шагам, почему так происходит, какие механизмы платформы запускаются при этом и как правильно устранить зависание интерфейса.

В чем заключается механизм проблемы

В отличие от тонкого клиента, где интерфейс отрисовывается нативным движком платформы, в веб-клиенте интерфейс строится в браузере с использованием структуры DOM и JavaScript. Программное переключение видимости колонок табличной части или динамических списков на сервере (в процедуре ПриСозданииНаСервере) либо на клиенте при открытии заставляет браузер полностью пересчитывать геометрию элементов страницы и позиционировать курсор.

В веб-клиенте эта перерисовка часто приводит к каскадному срабатыванию интерфейсных событий, в частности события ПриАктивизацииСтроки (вплоть до нескольких раз подряд при открытии одной формы). Если в этом обработчике написан тяжелый код, содержащий контекстные обращения к серверу (&НаСервере) или циклы, открытие формы блокируется на время выполнения всех сетевых запросов.

Способ 1. Исключение тяжелых серверных вызовов из события ПриАктивизацииСтроки

Проанализируем стандартные требования платформы к событию ПриАктивизацииСтроки. В синтакс-помощнике прямо указано, что в обработчике данного события крайне не рекомендуется выполнять синхронные вызовы процедур с директивой &НаСервере, так как они блокируют интерфейс при каждом перемещении фокуса и при обновлении геометрии таблицы.

Если получение данных с сервера действительно необходимо, используем директиву &НаСервереБезКонтекста, передавая только требуемый идентификатор или ссылку, чтобы исключить передачу всего контекста формы через HTTP-соединение:


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

&НаСервереБезКонтекста
Процедура ПолучитьДополнительныеДанныеНаСервере(Знач ЗаказПоставщику)
    // Оптимизированная выборка данных без сериализации формы
КонецПроцедуры

Способ 2. Защита от лишних срабатываний до полной инициализации формы

Чтобы исключить выполнение серверных процедур в момент, когда форма только загружается и веб-клиент перерисовывает колонки, введем переменную-флаг инициализации формы в модуле формы:


&НаКлиенте
Перем ФормаИнициализирована;

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    ФормаИнициализирована = Истина;
КонецПроцедуры

&НаКлиенте
Процедура ОплатыПриАктивизацииСтроки(Элемент)
    // Прерываем выполнение, если форма еще находится на этапе отрисовки
    Если Не ФормаИнициализирована Тогда
        Возврат;
    КонецЕсли;

    ОбработатьВыборСтроки();
КонецПроцедуры

Способ 3. Отсечение повторных вызовов для одной и той же строки

Веб-клиент может несколько раз активизировать одну и ту же строку при скрытии или отображении элементов. Чтобы не выполнять лишнюю работу, сохраняем идентификатор текущей строки в переменной модуля формы:


&НаКлиенте
Перем ИдентификаторПредыдущейСтроки;

&НаКлиенте
Процедура ОплатыПриАктивизацииСтроки(Элемент)
    Если Элемент.ТекущаяСтрока = ИдентификаторПредыдущейСтроки Тогда
        Возврат;
    КонецЕсли;

    ИдентификаторПредыдущейСтроки = Элемент.ТекущаяСтрока;
    
    ОбработатьВыборСтроки();
КонецПроцедуры

Способ 4. Использование обработчика ожидания (Debounce)

Если по событию активации строки требуется выполнять относительно тяжелую операцию, самым надежным паттерном платформы 1С является отложенный вызов через ПодключитьОбработчикОжидания с однократным запуском. Это объединяет множество событий в одно и предотвращает «залипание» интерфейса:


&НаКлиенте
Процедура ОплатыПриАктивизацииСтроки(Элемент)
    // Сбрасываем предыдущий вызов, если пользователь быстро листает строки
    ОтключитьОбработчикОжидания("ВыполнитьОбработкуСтрокиПоОжиданию");
    
    // Подключаем однократный вызов с минимальной задержкой в 0.1 секунды
    ПодключитьОбработчикОжидания("ВыполнитьОбработкуСтрокиПоОжиданию", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьОбработкуСтрокиПоОжиданию()
    // Здесь выполняются действия по обновлению данных формы
КонецПроцедуры

Способ 5. Настройка отладки веб-клиента для поиска скрытых циклов

Для быстрого обнаружения неоптимального кода, специфичного для директивы #Если ВебКлиент Тогда, настроим отладку для веб-клиента. Для этого в файле публикации информационной базы default.vrd на веб-сервере включим режим отладки:

<debug enable="true" url="tcp://АдресСервераОтладки:1560"/>

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

← На главную