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