Ускорить открытие формы в 1С чаще всего удаётся, если перестать считать при открытии то, что пользователю не нужно немедленно. Типичная история: в карточку договора или клиента добавили «все показатели» — долг, оборот за год, средний чек, — и они пересчитываются в ПриСозданииНаСервере. Решение: открыть форму со статичными данными сразу, а тяжёлый расчёт запустить фоновым заданием через подсистему «Длительные операции» БСП и дорисовать показатели после его завершения. Другой вариант — считать показатели только когда пользователь открыл соответствующую вкладку.

В примере ниже форма открывалась около 15 секунд, после переноса расчёта в фон — около двух, а показатели появлялись чуть позже. Но прежде чем что-то переносить, нужно убедиться, что тормозит именно расчёт.

Шаг 0. Найдите, что именно тормозит

Не гадайте. В конфигураторе включите замер производительности (Отладка → Замер производительности) и откройте форму. Замер покажет строки кода, на которые ушло больше всего времени. Типичные находки:

ПричинаПризнак в замереЧто делать
Тяжёлые запросы для показателейБольшая доля времени на Запрос.Выполнить() в ПриСозданииНаСервереФон, ленивая загрузка, оптимизация запроса
Много вызовов сервераДесятки коротких серверных вызовов из ПриОткрытииСобрать данные в один вызов
Обращение через точку к реквизитам ссылокЧтения объектов целикомПолучать реквизиты одним запросом
Динамический список с тяжёлым запросомВремя в получении данных спискаИндексы, упрощение запроса, отказ от лишних полей
Объёмное условное оформление и программное создание элементовВремя в построении формыУпростить, создавать элементы по требованию

Если причина — запрос, который можно ускорить индексом или переписыванием, сделайте это в первую очередь. Фоновое задание не ускоряет расчёт, а только убирает его с пути пользователя.

Вариант 1. Фоновый расчёт показателей через БСП

Как ускорить открытие формы в 1С: тяжёлый расчёт уходит в фон, форма открывается сразу
Как ускорить открытие формы в 1С: тяжёлый расчёт уходит в фон, форма открывается сразу

Расчёт — в общий модуль

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

1С
// Рассчитывает показатели договора для карточки.
//
// Параметры:
//  Параметры - Структура - Договор (ссылка), ДатаРасчета (дата)
//  АдресРезультата - Строка - адрес временного хранилища
//
Процедура РассчитатьПоказателиДоговора(Параметры, АдресРезультата) Экспорт

	Результат = Новый Структура("Задолженность, ОборотЗаГод, СреднийЧек", 0, 0, 0);

	// Здесь — запросы для расчёта показателей по Параметры.Договор

	ПоместитьВоВременноеХранилище(Результат, АдресРезультата);

КонецПроцедуры

В параметрах передавайте только простые значения: ссылки, даты, числа, строки. Объект и данные формы в фоновое задание не передаются.

Запуск — сразу при создании формы

Чтобы не тратить лишний вызов сервера, задание запускаю прямо в ПриСозданииНаСервере, а в ПриОткрытии только начинаю ожидание. Структуру с описанием задания храню в реквизите формы ДлительнаяОперация (тип «Произвольный»).

1С
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	// ... обычная инициализация формы

	Если Не Параметры.Ключ.Пустая() Тогда
		ЗапуститьРасчетПоказателей();
	КонецЕсли;

КонецПроцедуры

&НаСервере
Процедура ЗапуститьРасчетПоказателей()

	ПараметрыРасчета = Новый Структура;
	ПараметрыРасчета.Вставить("Договор", Объект.Ссылка);
	ПараметрыРасчета.Вставить("ДатаРасчета", ТекущаяДатаСеанса());

	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'Расчёт показателей договора'");

	ДлительнаяОперация = ДлительныеОперации.ВыполнитьВФоне(
		"РасчетПоказателейСервер.РассчитатьПоказателиДоговора", ПараметрыРасчета, ПараметрыВыполнения);

	Элементы.ГруппаПоказатели.Доступность = Ложь;
	Элементы.ДекорацияИдетРасчет.Видимость = Истина;

КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)

	Если ДлительнаяОперация = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	ПараметрыОжидания.ВыводитьОкноОжидания = Ложь;

	ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация,
		Новый ОписаниеОповещения("РасчетПоказателейЗавершение", ЭтотОбъект), ПараметрыОжидания);

КонецПроцедуры

&НаКлиенте
Процедура РасчетПоказателейЗавершение(Результат, ДополнительныеПараметры) Экспорт

	Элементы.ДекорацияИдетРасчет.Видимость = Ложь;
	Элементы.ГруппаПоказатели.Доступность = Истина;

	Если Результат = Неопределено Или Результат.Статус <> "Выполнено" Тогда
		Элементы.ДекорацияОшибкаРасчета.Видимость = Истина;
		Возврат;
	КонецЕсли;

	Показатели = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
	Задолженность = Показатели.Задолженность;
	ОборотЗаГод = Показатели.ОборотЗаГод;
	СреднийЧек = Показатели.СреднийЧек;

КонецПроцедуры

Декорация «Показатели рассчитываются…» вместо пустых полей — обязательна. Без неё пользователь увидит нули и решит, что задолженности нет.

Если задание закончится быстро (например, в файловой базе БСП может выполнить его сразу), ОжидатьЗавершение всё равно вызовет оповещение — отдельно обрабатывать этот случай не нужно.

Вариант 2. Считать по требованию

Если показатели лежат на отдельной вкладке, проще вообще не считать их, пока пользователь туда не зашёл. У группы страниц есть событие ПриСменеСтраницы:

1С
&НаКлиенте
Процедура СтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница)

	Если ТекущаяСтраница = Элементы.СтраницаПоказатели И Не ПоказателиЗагружены Тогда
		ЗагрузитьПоказателиНаСервере();
		ПоказателиЗагружены = Истина;
	КонецЕсли;

КонецПроцедуры

Для коротких расчётов (до пары секунд) этого достаточно. Для длинных — комбинируйте: при переходе на вкладку запускайте фоновое задание, как в первом варианте.

Другие приёмы, которые дают эффект

  • Один вызов сервера вместо многих. Собирайте всё, что нужно для открытия, в ПриСозданииНаСервере. Каждый лишний серверный вызов из ПриОткрытии — это сетевой обмен, особенно заметный в веб-клиенте и через интернет.
  • Реквизиты одним запросом. Вместо Объект.Контрагент.ИНН, Объект.Контрагент.ОсновнойДоговор.Валюта — получение нужных реквизитов одним запросом или функцией БСП ОбщегоНазначения.ЗначенияРеквизитовОбъекта.
  • Меньше элементов, создаваемых программно. Если элементы строятся в цикле при каждом открытии, подумайте, нельзя ли нарисовать их в конфигураторе и управлять видимостью.
  • Динамические списки на форме. Отключайте ненужные колонки и проверяйте запрос списка: он выполняется при каждой прокрутке.
  • Не держите расчёты в ПриЧтенииНаСервере без необходимости. Это событие вызывается и при перечитывании объекта после записи.

Ограничения подхода

  • Показатели появляются не сразу. Если без них нельзя работать с документом — например, они влияют на проверку при проведении, — фон не подходит, оптимизируйте запрос.
  • Запуск фонового задания стоит времени. Переносить в фон операции на доли секунды бессмысленно: форма откроется не быстрее, а сложность вырастет.
  • Каждое открытие формы — новое фоновое задание. При сотнях пользователей подумайте о кэшировании показателей, например в регистре сведений с периодическим обновлением регламентным заданием.
  • Если пользователь закрыл форму раньше завершения, задание доработает впустую. Для очень тяжёлых расчётов отменяйте его в ПриЗакрытии.
Сначала замер, потом решение. Половина «тяжёлых форм» лечится одним индексом или переписанным запросом, без фоновых заданий.

Когда тормозит не одна форма, а вся база, нужен системный подход — с ним помогает аудит производительности 1С. Точечные переделки форм и расчётов я делаю в рамках доработки 1С.

Коротко

  • Найдите причину замером производительности, а не догадкой.
  • Тяжёлые показатели считайте в фоне: запуск в ПриСозданииНаСервере, ожидание без окна в ПриОткрытии, результат через временное хранилище.
  • Показатели на отдельной вкладке загружайте при переходе на неё.
  • Показывайте пользователю, что идёт расчёт, а не пустые поля.
  • Не переносите в фон быстрые операции и данные, без которых нельзя работать с документом.