Почему тормозит переход с клиента на сервер при активном поиске в динамическом списке и как это исправить?

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

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

Выясняем причину: механизм передачи контекста

Проанализируем ситуацию. Когда мы используем директиву компиляции &НаСервере, платформа выполняет контекстный вызов. Это означает, что на сервер передаются абсолютно все данные формы: значения реквизитов, состояние элементов управления и, что самое важное, состояние ДинамическогоСписка.

Динамический список — это сложный объект, который хранит не только текст запроса, но и текущие пользовательские настройки: отборы, группировки, сортировки и параметры поиска. Если активен «Поиск» (который по своей природе отличается от жесткого отбора), система вынуждена выполнять следующие действия при каждом серверном вызове:

В результате простая «пустая» процедура превращается в тяжелую операцию из-за неявных действий платформы по синхронизации состояния списка.

Решение №1: Использование внеконтекстных вызовов

Самый простой и эффективный способ — исключить передачу данных динамического списка на сервер. Для этого заменим контекстный вызов &НаСервере на внеконтекстный &НаСервереБезКонтекста. Рассмотрим пример реализации.

Было (проблемный вариант):


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
    ОбработатьДанныеТекущейСтроки(Элемент.ТекущиеДанные.Ссылка);
КонецПроцедуры

&НаСервере
Процедура ОбработатьДанныеТекущейСтроки(Ссылка)
    // Здесь платформа тратит время на передачу всего контекста формы
    // включая тяжелые настройки поиска
КонецПроцедуры

Стало (оптимизированный вариант):


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
    Если Элемент.ТекущиеДанные <> Неопределено Тогда
        ОбработатьДанныеБезКонтекста(Элемент.ТекущиеДанные.Ссылка);
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ОбработатьДанныеБезКонтекста(Знач Ссылка)
    // На сервер передается только Ссылка. Контекст формы и 
    // состояние динамического списка остаются на клиенте.
    // Фризы исчезают.
КонецПроцедуры

При использовании &НаСервереБезКонтекста платформа не пересылает данные динамического списка, и серверу не нужно заново вычислять поисковую выборку. Это сокращает время перехода в десятки раз.

Решение №2: Использование обработчика ожидания

Событие ПриАктивизацииСтроки коварно тем, что оно срабатывает очень часто: при каждом клике, при перемещении стрелками на клавиатуре и даже при программном обновлении списка. Если пользователь быстро пролистывает список, серверные вызовы могут «наслаиваться» друг на друга.

Рассмотрим, как внедрить небольшую задержку (дебаунсинг), чтобы серверный вызов происходил только тогда, когда пользователь зафиксировал курсор на определенной строке хотя бы на 0.2–0.5 секунды.


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
    // Отключаем предыдущий обработчик, если пользователь нажал кнопку быстро
    ОтключитьОбработчикОжидания("ВыполнитьСервернуюОперацию");
    
    // Подключаем заново — вызов произойдет через 0.3 секунды покоя
    ПодключитьОбработчикОжидания("ВыполнитьСервернуюОперацию", 0.3, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьСервернуюОперацию()
    ДанныеСтроки = Элементы.Список.ТекущиеДанные;
    Если ДанныеСтроки <> Неопределено Тогда
        ВыполнитьПолезнуюРаботуНаСервере(ДанныеСтроки.Ссылка);
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ВыполнитьПолезнуюРаботуНаСервере(Ссылка)
    // Логика обработки
КонецПроцедуры

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

Разберем разницу: Поиск (Alt+F) против Отбора

Важно понимать, почему при обычном отборе (через НастройкиКомпоновкиДанных) тормозов нет, а при поиске через интерфейсную строку они появляются. Выясним причину:

  1. Отбор: Накладывается непосредственно на поле базы данных. Если поле проиндексировано, СУБД мгновенно находит нужные записи. Платформа четко знает границы выборки.
  2. Интерфейсный поиск (Alt+F): Часто работает как полнотекстовый поиск или как поиск по подстроке во всех видимых колонках сразу. Это заставляет 1С строить временные таблицы или выполнять сложные объединения, чтобы определить, какие ссылки соответствуют критерию. При контекстном вызове эта работа частично дублируется на сервере для «проверки» контекста формы.

Рекомендация: Если вы знаете, что пользователи будут часто искать данные по конкретной колонке (например, «Артикул»), лучше вывести над списком отдельное поле ввода для установки прямого Отбора, чем заставлять их использовать универсальный поиск.

Дополнительные методы оптимизации

Если специфика задачи всё же требует использования контекстного вызова (например, нужно изменить состояние других элементов формы), обратим внимание на следующие настройки:

Подведем итог: Главный виновник задержек — передача тяжелого состояния поиска внутри контекста формы. Переход на &НаСервереБезКонтекста в сочетании с ПодключитьОбработчикОжидания является «золотым стандартом» для разработки отзывчивых интерфейсов в 1С.

← На главную