При разработке в 1С:Предприятии мы часто сталкиваемся с необходимостью выполнения кода на сервере из клиентской части приложения. Для этого используются специальные директивы, такие как &НаСервере и &НаСервереБезКонтекста. Разберем подробно, в чем заключается их отличие, как это влияет на производительность и как мы можем оптимизировать работу наших приложений.
Давайте сначала выясним, что же такое контекст формы. Контекст формы — это, по сути, вся совокупность данных, которые связаны с конкретной формой. Мы говорим о всех ее реквизитах, а также о методах и свойствах, которые определены в модуле формы. Этот контекст формирует набор доступных объектов, переменных, процедур и функций, с которыми мы можем работать.
Когда мы вызываем серверную процедуру или функцию из клиентской части формы с директивой &НаСервере, происходит целый процесс:
Мы видим, что это достаточно сложный и многоступенчатый процесс, который может быть весьма затратным, особенно если контекст формы содержит большой объем данных.
&НаСервере против &НаСервереБезКонтекстаОсновное различие между этими двумя директивами заключается в том, какой объем данных передается на сервер и какой доступ к данным формы имеет серверная процедура.
Вызов &НаСервере (контекстный)
При использовании директивы &НаСервере на сервер передаются все данные формы, которые были изменены на клиенте с момента предыдущего контекстного серверного вызова. На сервере происходит полноценная инициализация методов формы и серверной копии данных формы. Это означает, что внутри такой серверной процедуры мы имеем полный доступ к реквизитам формы, ее элементам и методам.
Когда это оправдано? Контекстный вызов может быть оправдан, когда платформа может самостоятельно оптимизировать объем передаваемых данных (например, для табличных документов передаются только измененные области) и когда затраты на инициализацию контекста оправдываются снижением трафика и числа вызовов. Также он необходим, если серверный код действительно нуждается в доступе ко всем данным формы.
Рассмотрим пример:
&НаСервере
Процедура ОбработатьДанныеФормыНаСервере()
// Здесь мы имеем доступ ко всем реквизитам формы
// Например, к реквизиту "ТекстовоеПоле"
Если Не ЗначениеЗаполнено(ТекстовоеПоле) Тогда
Сообщить("Текстовое поле не заполнено!");
Возврат;
КонецЕсли;
// Выполняем действия с данными формы
РезультатОбработки = "Данные обработаны: " + ТекстовоеПоле;
КонецПроцедуры
Вызов &НаСервереБезКонтекста (внеконтекстный)
При внеконтекстной передаче управления на сервер передаются только те данные, которые мы явно указали в параметрах процедуры или функции. Доступа к контексту формы (реквизитам, параметрам, элементам) у такой процедуры или функции на сервере нет. Это означает, что мы не можем обратиться напрямую к ТекстовоеПоле или Элементы.МояТаблица внутри такой процедуры.
Когда это целесообразно? Внеконтекстные вызовы позволяют значительно уменьшить нагрузку на серверный вызов и не занимать сервер обработкой и хранением ненужной информации. Это особенно полезно, когда нам нужно выполнить на сервере какую-то операцию, которая не требует доступа ко всему контексту формы, а лишь к нескольким конкретным значениям.
Посмотрим на пример:
&НаСервереБезКонтекста
Процедура ВыполнитьОперациюБезКонтекста(Параметр1, Параметр2)
// Здесь у нас есть доступ только к Параметр1 и Параметр2
// Обращение к реквизитам формы, например, ТекстовоеПоле, вызовет ошибку
Результат = Параметр1 + Параметр2;
// ... выполняем другие действия, не требующие контекста формы
СообщитьНаКлиенте("Результат операции: " + Результат);
КонецПроцедуры
// Вызов с клиента:
// ВыполнитьОперациюБезКонтекста(МойРеквизит1, МойРеквизит2);
Производительность: Мы уже упоминали, что контекстный вызов — это довольно затратный процесс. Он включает упаковку, передачу, разворачивание контекста на сервере, выполнение кода, а затем обратную упаковку, передачу и синхронизацию на клиенте. Внеконтекстные вызовы, напротив, значительно уменьшают объем передаваемых данных и, как следствие, нагрузку на сеть и сервер, что приводит к повышению производительности.
Ограничения: Важно помнить, что в некоторых клиентских обработчиках событий форм (например, ПередЗаписью, ПослеЗаписи, ПередЗакрытием, ПриЗакрытии) не допускается вызов контекстных серверных процедур. В таких случаях использование &НаСервереБезКонтекста является единственным возможным вариантом.
Для того чтобы наши приложения работали быстро и стабильно, нам необходимо придерживаться определенных принципов оптимизации:
Минимизация серверных вызовов
Каждый серверный вызов, даже если он передает небольшой объем данных, требует времени на установление соединения, передачу служебной информации и обработку. Мы можем столкнуться с задержками, например, до 1,5 секунд при работе тонкого клиента через медленные каналы связи (GPRS). Поэтому стремитесь минимизировать количество серверных вызовов, инициируемых нашим кодом. Объединяйте несколько небольших операций в один серверный вызов, если это возможно.
Уменьшение объема передаваемых данных
Это одна из ключевых стратегий. Мы уже выяснили, что &НаСервереБезКонтекста помогает в этом. Кроме того, мы можем:
Кэширование
Система 1С использует многоуровневое кэширование (в пределах сеанса и в пределах формы). Это означает, что платформа запоминает полученную информацию и не передает её повторно при аналогичных вызовах в том же сеансе или для той же формы. Мы должны учитывать это при проектировании наших решений, чтобы не запрашивать одни и те же данные многократно.
Работа с большими объемами данных
РазделитьФайл() и ОбъединитьФайлы() для разбиения файла на части и последующей их сборки.Использование инструментов профилирования и мониторинга
Для выявления "узких мест" и оценки производительности наших решений крайне важно использовать профилировщик кода и инструменты мониторинга. Технологический журнал 1С также может предоставить ценную информацию о суммарном времени выполнения запросов и серверных вызовов, помогая нам понять, где именно возникают задержки.
Архитектурный подход
Мы должны помнить, что интерфейс управляемого приложения 1С ориентирован на работу через Интернет и по низкоскоростным каналам связи. Платформа содержит механизмы оптимизации, но разработчик также должен придерживаться определенных методик, чтобы максимально использовать эти возможности и не создавать излишнюю нагрузку.
Чтобы наглядно ощутить разницу и понять, как объем данных влияет на производительность и потребление памяти, мы можем провести эксперимент:
&НаСервере: Создайте процедуру, которая вызывается с директивой &НаСервере. Внутри этой процедуры не обязательно что-то делать с нашим объемным реквизитом, достаточно самого факта его передачи.&НаСервереБезКонтекста: Создайте другую процедуру с директивой &НаСервереБезКонтекста, которая не принимает наш объемный реквизит в качестве параметра.ragent.exe, rmngr.exe, rphost.exe) в диспетчере задач или специализированных утилитах.Вы заметите, что одиночные вызовы &НаСервере или &НаСервереБезКонтекста могут не показать существенной разницы, так как накладные расходы на каждый вызов и резервирование памяти могут скрыть эффект. Однако, если мы будем выполнять эти вызовы в цикле (например, 100-1000 раз), то разница станет очевидной. При циклическом вызове &НаСервере вы увидите значительное увеличение сетевого трафика и, возможно, заметный рост потребления памяти серверным процессом, а также заметите существенное снижение скорости выполнения по сравнению с &НаСервереБезКонтекста.
Этот эксперимент поможет нам лучше понять, насколько важен осознанный выбор между контекстными и внеконтекстными серверными вызовами для создания высокопроизводительных приложений в 1С:Предприятии.
← К списку