Каталог решений - Данные формы и оптимизация обмена с сервером

Данные формы и оптимизация обмена с сервером

Данные формы и оптимизация обмена с сервером

В наличии

Почему может сильно тормозить форма, где есть "ДанныеФормыКоллекция", "ДанныеФормыДерево" и им подобные, и как этого избежать.

Категория:

Описание

«ДанныеФормы…» Синтакс-помощник не балует нас избыточной информацией, сообщая лишь, что объект этого рода, в общем случае, «предназначен для моделирования коллекций в данных управляемой формы» и «может использоваться в реквизитах управляемой формы». Для «ДанныеФормыКоллекция», по идее, моделируется таблица значений, для «ДанныеФормыДерево» — дерево значений, и так далее. Общеизвестно, на ИТС и в статьях разжёвано, что эти объекты живут на клиенте с целью адекватно отобразить, в т.ч. в связке с элементами УФ, те или иные данные; а также, что они доступны и на сервере как минимум при передаче всего контекста формы. Моделировать можно коллекции прикладных объектов из БД, а можно и свои, временные, созданные прямо в форме для служебных и рабочих надобностей. Вот о них и пойдёт речь — о моделях коллекций, являющихся реквизитами управляемой формы и отражающих некие не единичные объёмы данных.

Поскольку поведение этих моделей отличается в разных версиях платформы, возьмём 8.2.19.106 и 8.3.5.1119; для чистоты эксперимента создадим для каждой версии совсем пустую конфигурацию и будем гонять в режиме тонкого клиента, безо всяких совместимостей, замеряя производительность с помощью штатных средств платформы.

Сделаем внешнюю обработку, в ней форму, и для этой формы создадим два реквизита — с типом «Таблица значений» и с типом «Дерево значений» (разумеется, они покажутся в скобках как несуществующие на клиенте). Создадим по 4 реквизита-колонки к каждому из этих, дадим им типы — строковый (250), число (15.2), дата (дата-и-время), булево. Желающие могут поэкспериментировать со ставшими возможными в 8.3 «произвольными», а также с вложением всяких других моделей коллекций типа «матрёшка», но мы будем работать с этими простыми данными, чья возможность сериализации штатным образом очевидна. На интерфейсе, в элементах формы, ничего делать не станем.

Заполним таблицу значений — сначала по 1000 строк, потом будем пробовать больше. Дерево значений, а точнее, моделирующая его коллекция, понадобится как «гиря», сразу дающая разницу в объёмах данных на порядки. Строковую колонку везде забьём мусором под все 250 символов.

Итак, что нам интересно? Допустим, мы делаем внешнюю универсальную обработку, в чьих реквизитах формы никак не задействованы сущности БД, но по ряду причин очень нужно использовать большие модели коллекций. Например, это обзор файлов на клиентском ПК — дерево каталогов и некая таблица значений нужных юзверю файлов. Главное, что нам совершенно незачем обрабатывать все данные на сервере, мы добровольно отказались от индексации таблицы значений и вообще хотим в первую очередь оптимизировать передачу данных между клиентом и сервером. Подчеркну — дерево большое, таблица значений сравнительно маленькая.

Исходная задача — всего лишь по каким-то нашим нуждам поработать с таблицей значений, «вынимаемой» из её модели. Да, можно возразить, что мол «чего тебе не хватает» — и сортировка есть, и поиск, и обход колонок можно смоделировать — но вот допустим, для эксперимента. Я, может, хочу СКД-образную выборку запилить по таблице, с ветками «И»-«ИЛИ», по заданной юзверем логике.

Вроде бы это просто — вызвать контекстную серверную процедуру и там выполнить «ДанныеФормыВЗначение», вуаля. Но здесь и начинаются подводные камни, потому как вместе с безусловно нужной нам моделью таблицы значений на сервер в рамках контекста тащится и огроменная «ДанныеФормыДерево», которая вообще там не нужна.

К сожалению, разработчики платформы не дали нам возможности избирательно управлять передачей контекста формы между клиентом и сервером. Флаг «Использовать всегда» для реквизитов этих моделей вообще не играет роли, а другого и нет, и в результате вызов сервера превращается в тормоза и недопустимо высокий объём отправляемых данных.

Очевидно, что вызов должен быть внеконтекстным. Но тогда коллекции недоступны, и их надо как-то в целевую серверную процедуру передать. Тут начинается разница — в 8.2 можно передать «ДанныеФормы» как аргумент на сервер, их передача происходит без ошибок и без потерь, но на ИТС читаем, что это очень некомильфо, что в принципе логично, т.к. кто его знает, как оно там размещается, где в памяти болтается, куда на сервере приложений девается и как себя поведёт при изменении без указания «Знач».

Всякие «ХранилищеОбщихНастроек.Сохранить» или «ЗначениеВСтрокуВнутр» неприменимы на клиенте и отпадают.

Казалось бы, используем «ПоместитьВоВременноеХранилище» (естественно, с соблюдением и пониманием, какие ключи нужны и сколько времени оно проживёт — ну, нам на один вызов, и хватит). Тем более, что в СП никаких ограничений на этот счёт не указано, а значит, находясь в форме, вполне можно поработать с временным хранилищем. И в 8.2 это удаётся без проблем, и мы получаем вожделенный результат. Сделали внеконтекстно вызываемую процедуру, на клиенте помещаем модель-коллекцию в хранилище, передаём адрес как аргумент этой процедуре, а в ней, на сервере, получаем из хранилища. Все счастливы, всё работает, объём данных минимален благодаря тому, что мы сами решаем, какие объекты помещать и передавать — т.е. только и исключительно нужную нам таблицу, а никакое не дерево.

Но в 8.3 нас ждёт неприятный сюрприз: 8.3.4 просто заявляет, что подобные объекты «не могут быть помещены в хранилище», а 8.3.5 громко падает с ошибкой. Скромно осмелюсь полагать, что это просто временная недоработка писателей платформы, ибо если данные можно было передавать в 8.2, то что мешает повторить достигнутое? Поэтому надеюсь, что примерно к 8.3.10 это аккуратно доделают, а не оставят как сейчас и не объявят «фичей», подогнав заумное обоснование.

Что делать? А делать сериализацию своими силами. Это даже лучше, всё под нашим контролем. Приведу кусок кода с контекстным и внеконтекстным вызовами, которые дали мне статистику.

&НаСервереБезКонтекста
Процедура Сгонять_СерверБезКонтекста(стро)
   
рЧтениеХМЛ=Новый ЧтениеXML;
   
рЧтениеХМЛ.УстановитьСтроку(стро);
   
рТаблицаЗначенийС=СериализаторXDTO.ПрочитатьXML(рЧтениеХМЛ);
   
Сообщить(«К-во табзнач: «+рТаблицаЗначенийС.Количество());
КонецПроцедуры

&НаКлиенте
Процедура СгонятьБезКонтекста(Команда)
   
рЗаписьХМЛ=Новый ЗаписьXML;
   
рЗаписьХМЛ.УстановитьСтроку();
   
СериализаторXDTO.ЗаписатьXML(рЗаписьХМЛ,рТаблицаЗначений);
   
Сгонять_СерверБезКонтекста(рЗаписьХМЛ.Закрыть());
КонецПроцедуры

&НаСервере
Процедура Сгонять_Сервер()
   
Сообщить(«К-во табзнач: «+рТаблицаЗначений.Количество());
КонецПроцедуры

&НаКлиенте
Процедура Сгонять(Команда)
   
Сгонять_Сервер();
КонецПроцедуры


В результате получаем адекватную передачу «ДанныеФормыКоллекция» на сервер, и опять же, избирательно, что экономит нам объёмы и время. Причём это именно полноценный объект, с которым вполне можно работать, хотя мы даже не указали сериализатору тип значения, читаемого из xml, он сам догадался.

Поставив ряд экспериментов, можно убедиться, что при прочих равных передача контекста всей формы это не худший, а порой и оптимальный вариант, но только если а) в ней нет чего-то тяжёлого и/или б) всё или почти всё реально нужно на сервере. В случаях же, когда на форме преизрядно разных данных, и среди них объёмистые модели коллекций, проще использовать сериализацию только нужных данных и их передачу во внеконтекстные серверные процедуры. В таблице на приложенном рисунке приведены результаты экспериментов — вызовов вышеуказанного кода — и краткие пояснения. Извиняюсь, что не включаю таблицу в текст статьи — но html-редактора ИС в очередной раз не превозмог (((

Зелёным цветом показаны успешные варианты, когда мы сэкономили, а красным — когда наоборот)

Заметим, что объём передаваемых данных в нашем случае порождён обычной строкой, куда свернулся xml, а значит, её тоже можно чем-нибудь «ужать», и вопрос, как всегда, во времязатратах относительно выигрыша по размеру.

Также заметим, что в 8.2 объём принятых данных не меняется, тогда как в 8.3 при нашем способе принимается столько же, сколько передавалось. Не берусь объяснить сей эффект — надо больше знать о «глубинах».

Однозначного рецепта нет, решать приходится по ситуации, но способ максимально облегчить обмен, поработать на сервере только с нужными моделями коллекций, и взятыми из них реальными коллекциями, у нас есть. Успеха!


has been added to your cart:
Оформление заказа