После очередного обновления конфигурации «1С:Зарплата и управление персоналом» (ЗУП) многие технические специалисты и пользователи сталкиваются с крайне неприятной проблемой: документ «Табель учета рабочего времени» начинает сильно тормозить. Любое простое действие — например, попытка отредактировать количество часов или тип времени в ячейке дня — вызывает зависание интерфейса на 20–25 секунд. При этом серверная часть отрабатывает мгновенно. Разберем детально, почему это происходит и как исправить эту проблему раз и навсегда.
Проанализируем типичную ситуацию. Разработчик запускает замер производительности в конфигураторе 1С, чтобы локализовать проблемный участок кода. Результаты замера показывают поразительную картину: процедура ДанныеДляРедактированияВХранилище выполняется на сервере всего за 0,0005 секунды. Однако на пути возврата управления с сервера обратно на клиент система уходит в глубокое «раздумье» на десятки секунд. Процессор клиентской машины в этот момент может быть загружен на 100%.
Почему замер производительности показывает микросекунды на самом сервере, а реальное время ожидания огромно? Всё дело в том, что стандартный замер производительности фиксирует только чистое время выполнения кода на сервере. Он не учитывает время, затрачиваемое платформой на сериализацию данных на стороне сервера, передачу их по сети и последующую десериализацию на стороне клиента.
Рассмотрим исходный код проблемной процедуры, которая вызывается в контексте формы:
&НаСервере
Процедура ДанныеДляРедактированияВХранилище(КлючСтрокиТаблицыПредставления, НомерДня)
ДанныеДляРедактирования = ДанныеДляРедактирования(КлючСтрокиТаблицыПредставления, НомерДня);
Если ПустаяСтрока(АдресРедактируемыхДанных) Тогда
АдресРедактируемыхДанных = ПоместитьВоВременноеХранилище(ДанныеДляРедактирования, УникальныйИдентификатор);
Иначе
ПоместитьВоВременноеХранилище(ДанныеДляРедактирования, АдресРедактируемыхДанных);
КонецЕсли;
КонецПроцедуры
Данная процедура объявлена с директивой компиляции &НаСервере. Это означает, что вызов является контекстным. При его выполнении платформа 1С совершает следующие действия:
ДанныеДляРедактированияВХранилище за доли миллисекунды.Именно на шагах упаковки-распаковки и сетевой передачи данных происходит катастрофическая потеря производительности. Если форма «тяжелая», этот процесс занимает десятки секунд.
В документе «Табель» содержится множество вспомогательных данных. В современных релизах ЗУП 3.1 разработчики фирмы «1С» активно используют механизмы учета в разрезе территорий и условий труда. В форме документа присутствуют скрытые или вспомогательные коллекции данных, которые инициализируются и заполняются справочной информацией:
После обновления базы данных или при накоплении истории учета объемы этих справочников существенно возрастают. Если в информационной базе не настроены жесткие отборы, в контекст формы документа «Табель» могут неявно загружаться тысячи элементов этих справочников. Как только объем передаваемой структуры превышает критический рубеж, сериализация контекста начинает полностью парализовать производительность клиентского приложения.
Самый эффективный и методологически верный способ решить проблему — избавиться от передачи контекста формы туда, где он абсолютно не нужен. Нам необходимо переписать процедуру так, чтобы она вызывалась с директивой &НаСервереБезКонтекста.
Многие разработчики ошибочно полагают, что сделать это невозможно, так как процедура оперирует данными документа. Однако детальный анализ кода показывает, что процедуре требуются только конкретные параметры:
КлючСтрокиТаблицыПредставления;НомерДня;АдресРедактируемыхДанных (переменная формы, хранящая адрес во временном хранилище);УникальныйИдентификатор формы (для создания временного хранилища).Разберем по шагам, как переписать этот участок кода. Создадим новую бесконтекстную функцию на сервере, которая будет принимать все параметры явно, выполнять работу и возвращать полученный адрес временного хранилища обратно на клиент.
&НаКлиенте
Процедура ПриРедактированииДняТабеля(КлючСтроки, НомерДня)
// Вызываем бесконтекстный серверный метод, передавая только необходимые значения
АдресРедактируемыхДанных = ПолучитьДанныеДляРедактированияБезКонтекста(
КлючСтроки,
НомерДня,
АдресРедактируемыхДанных,
УникальныйИдентификатор
);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьДанныеДляРедактированияБезКонтекста(Знач КлючСтроки, Знач НомерДня, Знач ТекущийАдрес, Знач УникальныйИдентификаторФормы)
// Вызываем функцию получения данных.
// Обратите внимание: функция "ДанныеДляРедактирования" также должна быть перенесена в общий модуль
// или объявлена без контекста формы!
ДанныеДляРедактирования = ДанныеДляРедактирования(КлючСтроки, НомерДня);
НовыйАдрес = ТекущийАдрес;
Если ПустаяСтрока(НовыйАдрес) Тогда
НовыйАдрес = ПоместитьВоВременноеХранилище(ДанныеДляРедактирования, УникальныйИдентификаторФормы);
Иначе
ПоместитьВоВременноеХранилище(ДанныеДляРедактирования, НовыйАдрес);
КонецЕсли;
Возврат НовыйАдрес;
КонецФункции
Проанализируем преимущества такого подхода. При вызове &НаСервереБезКонтекста платформа передает на сервер только четыре простых параметра (идентификаторы и строки). Контекст всей тяжелой формы документа «Табель» остается нетронутым на клиенте. В результате время передачи данных сокращается с 25 секунд до 0,001 секунды. Пользователь даже не заметит задержки при переходе между ячейками.
Если по каким-то причинам полного отказа от контекстных вызовов добиться не удается, необходимо радикально облегчить сам контекст формы. Основной вес форме придают избыточные данные в связанных справочниках. Выполним оптимизацию наполнения этих коллекций:
Территории и связанные с ними данные подчинены организации. В форме «Табеля» всегда выбрана конкретная организация. Необходимо убедиться, что при заполнении списков выбора или табличных частей на клиенте запрашиваются только те элементы справочников, которые относятся к текущей организации документа.Территории и УсловияТруда на наличие дублей и помеченных на удаление объектов. Если база ведется давно, там скапливаются сотни неактивных записей. Исключите их передачу в форму. На практике, если размер коллекции на форме не превышает 500-1000 элементов, сериализация выполняется мгновенно.Методология разработки на управляемой платформе «1С:Предприятие 8.3» настойчиво рекомендует минимизировать объем данных, хранящихся непосредственно в реквизитах формы. Рассмотрим общие архитектурные правила, которые помогут избежать подобных проблем в будущем:
ПоместитьВоВременноеХранилище) и передавайте на клиент только строковые адреса этих данных.Таким образом, сочетание перевода критических процедур в бесконтекстный режим работы и грамотная очистка контекста формы от избыточных данных позволяют полностью восстановить быстродействие документа «Табель учета рабочего времени» даже на крупных информационных базах 1С:ЗУП.