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