При работе со справочниками и документами в управляемом интерфейсе 1С разработчики нередко сталкиваются с проблемой: при попытке прокрутить динамический список вверх или вниз интерфейс «замирает» на несколько секунд. Проблема становится особенно заметной при использовании файловых баз, активных группировок и наложении программных отборов.
Разберем детально, почему механизм динамического считывания начинает терять производительность, какие архитектурные ограничения платформы влияют на скорость работы и как шаг за шагом оптимизировать форму списка.
Проанализируем основные факторы, вызывающие зависания при навигации по строкам:
ДинамическоеСчитываниеДанных приводит к тому, что платформа пытается загрузить в память клиентского приложения всю выборку целиком. При наличии нескольких тысяч записей это вызывает резкий рост потребления памяти и freeze-эффект.ПриАктивизацииСтроки или ПриПолученииДанныхНаСервере с контекстными серверными вызовами заставляет клиент отправлять запросы на сервер при каждом перемещении фокуса.Если для динамического списка задаются условия отбора или сортировки, обязательно проверяем индексы полей в конфигураторе.
Рассмотрим порядок настройки:
Контрагенты).Менеджер).Индексировать или Индексировать с доп. упорядочиванием (если по этому же полю выполняется регулярная сортировка).Часто в процедуре ПриСозданииНаСервере отбор по текущему пользователю или подразделению накладывается через прямое добавление элементов в коллекцию Список.Отбор.Элементы. Рассмотрим пример такого кода:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПользовательСеанса = ПользователиИнформационнойБазы.ТекущийПользователь();
// Установка отбора по менеджеру
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Менеджер");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Справочники.Пользователи.НайтиПоИмени(ПользовательСеанса.Имя);
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецПроцедуры
Проанализируем важные правила работы с программными отборами:
НайтиПоНаименованию или НайтиПоИмени выполняет дополнительный запрос к базе. Ссылку на текущего пользователя лучше получать из параметров сеанса.Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор, чтобы платформа строила оптимальный план запроса.Поскольку группировки в динамическом списке являются одной из главных причин торможения, рассмотрим альтернативные варианты компоновки интерфейса:
Чтобы точно определить, какой именно SQL-запрос генерирует платформа при прокрутке списка, настроим сбор технологического журнала. Это позволит увидеть длительность выполнения запросов и выявить неоптимальные конструкции.
Для регистрации событий СУБД и контекста исполнения создадим файл logcfg.xml в каталоге настроек платформы (bin/conf):
<config xmlns="v8.1c.ru/v8/tech-log">
<log location="C:\LOGS\1C_Queries" history="24">
<event>
<eq property="name" value="DBMSSQL"/>
<gt property="duration" value="100000"/>
</event>
<event>
<eq property="name" value="DBV8DBEngine"/>
<gt property="duration" value="100000"/>
</event>
<property name="all"/>
</log>
</config>
Событие DBV8DBEngine собирает информацию о запросах к файловой базе данных, а DBMSSQL — к Microsoft SQL Server. Параметр duration задает порог длительности в микросекундах (в примере — от 100 мс).
Для восстановления высокой скорости работы динамического списка в 1С необходимо соблюдать комплекс мер: включить флаг динамического считывания, проиндексировать реквизиты, участвующие в отборах и сортировках, исключить избыточные группировки в форме и очистить обработчик ПриАктивизацииСтроки от синхронных серверных вызовов.