В процессе разработки на платформе 1С:Предприятие 8.3 (особенно в тонком клиенте) программисты часто сталкиваются с существенным падением производительности при работе с большими таблицами значений. Ситуация становится критической, когда таблица содержит тысячи строк и сотни колонок, созданных динамически. Стандартный механизм синхронизации данных формы между клиентом и сервером начинает давать сбои, вызывая заметные "лаги". Рассмотрим подробнее, почему это происходит и какие архитектурные решения позволяют обойти это ограничение.
Проанализируем механику работы управляемого приложения. Когда мы вызываем серверную процедуру &НаСервере, платформа выполняет сериализацию контекста формы. Если в реквизитах формы находится объект типа ДанныеФормыКоллекция (аналог таблицы значений на форме), система передает не только сами данные, но и описание структуры.
В случае, если в таблице, например, 400 динамических колонок, накладные расходы на описание метаданных каждой колонки при каждом вызове сервера становятся огромными. Платформа проверяет типы, связи и изменения для каждой ячейки. Выясним основную причину: даже если данные в таблице не менялись, сам факт наличия огромного количества программно созданных колонок заставляет механизм сериализации работать на пределе возможностей. Замеры показывают, что разница в скорости вызова сервера между пустой и заполненной таблицей может достигать 10 и более раз.
Это наиболее эффективный метод, позволяющий полностью исключить передачу тяжелой таблицы значений через контекст формы. Суть метода заключается в том, что сама таблица (объект ТаблицаЗначений) физически находится на сервере, а на клиенте хранится только строковый адрес (ссылка) на эти данные.
Разберем по шагам алгоритм реализации этого подхода:
АдресТЗ (тип Строка).АдресТЗ в серверную процедуру &НаСервереБезКонтекста.Рассмотрим пример кода для помещения таблицы в хранилище:
&НаСервере
Процедура СохранитьТаблицуНаСервере()
// Предположим, ТЗ_Данные - это наша тяжелая таблица
ТЗ_Данные = СформироватьОгромнуюТаблицу();
// Важно использовать УникальныйИдентификатор формы,
// чтобы данные удалились автоматически после закрытия окна
АдресТЗ = ПоместитьВоВременноеХранилище(ТЗ_Данные, ЭтаФорма.УникальныйИдентификатор);
КонецПроцедуры
При использовании этого метода вызовы &НаСервереБезКонтекста будут происходить мгновенно, так как адрес — это всего лишь короткая строка.
Если отказаться от временного хранилища невозможно, следует проанализировать использование процедур. Основная ошибка — использование &НаСервере там, где данные формы (вся таблица) для работы процедуры не нужны. Выясним разницу:
Если вам нужно просто получить какой-то расчет на основе части данных, передавайте на сервер массив строк или структуру, а не всю таблицу целиком. Это критически важно для таблиц с динамическими колонками, так как &НаСервереБезКонтекста не инициирует синхронизацию структуры ДанныеФормыКоллекция.
Если таблица значений не выведена на экран для пользователя, а используется только как буфер данных (например, для отрисовки ТабличногоДокумента), хранить её в реквизите формы с типом "Таблица значений" (ДанныеФормыКоллекция) — плохая практика.
Посмотрим на альтернативу: использование типа Массив, содержащего объекты типа Структура. Массивы и структуры сериализуются платформой значительно быстрее, чем коллекции данных формы. Это связано с тем, что у структур нет "обвязки" для взаимодействия с элементами управления (события выбора, пометки, оформления и т.д.).
Часто возникает вопрос: не потеряются ли данные, если рабочий процесс сервера (rphost) перезапустится или произойдет переключение на другой процесс в кластере? Платформа 1С гарантирует репликацию временного хранилища внутри кластера. Однако, чтобы минимизировать риски и обеспечить производительность, придерживайтесь следующих правил:
ЭтаФорма.УникальныйИдентификатор при вызове ПоместитьВоВременноеХранилище. Это защитит память сервера от утечек.ПолучитьИзВременногоХранилища). В этом случае стоит подумать о хранении данных в промежуточных регистрах сведений.В некоторых случаях лаги связаны не с мощностью сервера, а с пропускной способностью канала. Платформа поддерживает различные режимы сжатия данных. Рассмотрим параметры запуска тонкого клиента:
/TComp -None — отключение сжатия. Помогает, если процессор клиента слаб, а сеть очень быстрая./TComp -Deflate — стандартное сжатие. Оптимально для большинства случаев.Как показала практика обсуждения, изменение параметров сжатия редко решает проблему 400 колонок, так как основная задержка происходит на этапе формирования пакета данных (сериализации) на стороне сервера или клиента, а не во время передачи по сети.
Проанализировав проблему, мы можем сделать вывод: для работы с динамическими таблицами планирования (5000 строк и более) самым надежным и быстрым способом является хранение оригинального объекта ТаблицаЗначений во временном хранилище.
Если же данные всё же должны быть на клиенте, старайтесь минимизировать количество колонок в реквизитах формы. Помните, что пользователь физически не может одновременно работать с 400 колонками — возможно, стоит пересмотреть интерфейс в пользу отображения только необходимых данных, подгружая остальные "по требованию" через &НаСервереБезКонтекста.