Как ускорить передачу большого табличного документа с сервера на клиент?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке сложных отчетов или печатных форм в среде 1С:Предприятие 8.3 разработчики часто сталкиваются с проблемой: отчет формируется на сервере за считанные секунды, но пользователь вынужден ждать полминуты или дольше, пока документ «прилетит» на клиент. В этой статье мы детально проанализируем, почему так происходит, и рассмотрим проверенные методы оптимизации этого процесса.

Почему передача табличного документа занимает так много времени?

Для начала разберем внутреннюю механику платформы. Когда мы возвращаем объект ТабличныйДокумент из серверной функции на клиент, 1С выполняет процедуру сериализации. Весь документ, включая структуру ячеек, форматирование, шрифты, границы и расшифровки, преобразуется в специфический XML-подобный формат. Если документ содержит 400 и более страниц (или десятки тысяч строк), объем этого промежуточного XML-текста может быть огромным. Даже если итоговый MXL-файл весит всего 9 Мб, его текстовое представление при передаче может «раздуться» в несколько раз.

Проанализируем основные факторы замедления:

  1. Сериализация XML: Процесс превращения объекта в текст и обратно на клиенте крайне ресурсоемок для процессора.
  2. Объем метаданных: Каждая ячейка может тянуть за собой информацию о стиле. Если стили не унифицированы, объем данных растет в геометрической прогрессии.
  3. Ожидание валидатора: Платформа проверяет целостность данных при десериализации на стороне клиента.

Решение 1: Использование реквизита формы и контекстного вызова

Один из самых эффективных способов — отказаться от возврата ТабличногоДокумента как результата функции и использовать механизм контекстной передачи. Рассмотрим, как это реализовать. Если табличный документ является реквизитом формы (типа ТабличныйДокумент), и мы заполняем его в процедуре &НаСервере, платформа оптимизирует передачу данных, подгружая их на клиент более эффективно.

Разберем пример кода, который позволяет ускорить вывод в разы:


&НаКлиенте
Процедура СформироватьОтчет(Команда)
    // Вместо получения объекта из функции, вызываем контекстный серверный метод
    СформироватьНаСервере();
КонецПроцедуры

&НаСервере
Процедура СформироватьНаСервере()
    // ОбъектОтчет.ТабДок - это реквизит формы
    ТабДок = ОбъектОтчет.ТабДок; 
    ТабДок.Очистить();
    
    // Код заполнения документа
    Для Итератор = 1 По 10000 Цикл
        Область = Макет.ПолучитьОбласть("Строка");
        Область.Параметры.Значение = Итератор;
        ТабДок.Вывести(Область);
    КонецЦикла;
КонецПроцедуры

В данном случае нам не нужно использовать ТабДок.Показать(), так как документ уже находится в поле табличного документа на форме. Как показывает практика, для очень больших документов (до 400 000 строк) такой метод сокращает время ожидания с десятков секунд до 3-4 секунд, так как платформа использует динамическую подгрузку видимых частей документа.

Решение 2: Передача через Двоичные Данные и временный файл

Если по каким-то причинам нам необходимо получить ТабличныйДокумент именно как отдельный объект (например, для последующего открытия в отдельном окне), мы можем обойти стандартную медленную сериализацию 1С. Выясним причину: запись в файл MXL на диске работает быстрее, чем преобразование объекта в XML-поток для передачи между сокетами.

Посмотрим на алгоритм реализации через временное хранилище с предварительной конвертацией в двоичные данные:


&НаСервере
Функция СформироватьИПоместитьВХранилище()
    ТабДок = Новый ТабличныйДокумент;
    // ... заполнение ТабДок ...
    
    // Записываем во временный файл во внутреннем формате MXL
    ИмяФайла = ПолучитьИмяВременногоФайла("mxl");
    ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.MXL);
    
    // Читаем файл в двоичные данные - это происходит очень быстро
    Данные = Новый ДвоичныеДанные(ИмяФайла);
    Адрес = ПоместитьВоВременноеХранилище(Данные, ЭтаФорма.УникальныйИдентификатор);
    
    УдалитьФайлы(ИмяФайла);
    Возврат Адрес;
КонецФункции

&НаКлиенте
Процедура КомандаСформировать(Команда)
    Адрес = СформироватьИПоместитьВХранилище();
    Данные = ПолучитьИзВременногоХранилища(Адрес);
    
    // На клиенте выполняем обратную операцию
    ИмяФайла = ПолучитьИмяВременногоФайла("mxl");
    Данные.Записать(ИмяФайла);
    
    НовыйТабДок = Новый ТабличныйДокумент;
    НовыйТабДок.Прочитать(ИмяФайла);
    НовыйТабДок.Показать("Ваш огромный отчет");
    
    УдалитьФайлы(ИмяФайла);
КонецПроцедуры

Этот «хак» позволяет передать «чистый» файл без лишних оберток сериализатора 1С, что на больших объемах дает существенный прирост скорости.

Решение 3: Сжатие данных (ZIP)

Поскольку формат MXL внутри является текстовым, он обладает колоссальной избыточностью. Проанализируем ситуацию: если наш файл весит 9 Мб, то после сжатия стандартным алгоритмом ZIP он может уменьшиться до 500-700 Кб. Передача полумегабайта данных по сети (даже локальной) происходит мгновенно.

Разберем, как добавить упаковку в наш процесс:

  1. На сервере сохраняем ТабличныйДокумент в MXL.
  2. Используем объект ЗаписьZipФайла для упаковки MXL-файла.
  3. Передаем ДвоичныеДанные архива на клиент.
  4. На клиенте распаковываем и читаем методом Прочитать().

Хотя упаковка и распаковка требуют времени процессора, экономия на передаче данных по сети и на обработке «раздутого» XML-сериализатора часто перекрывает эти затраты.

Решение 4: Оптимизация структуры самого документа

Иногда проблема кроется не в способе передачи, а в самом наполнении. Разберем по шагам, на что обратить внимание при формировании отчета:

Выводы

Подведем итог. Если ваш табличный документ «тормозит» при открытии: Во-первых, попробуйте перенести его в реквизиты формы — это самый «нативный» и быстрый путь для управляемого приложения. Во-вторых, если документ нужно открывать модально или в отдельном окне, используйте передачу через ДвоичныеДанные и временные файлы MXL, чтобы миновать медленный стандартный сериализатор. В-третьих, не забывайте про сжатие данных, если работа идет через интернет или медленные каналы связи.

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

← На главную