В практике разработки на платформе 1С:Предприятие 8.3 часто встречается ситуация: в форме списка реализована логика в событии ПриАктивизацииСтроки. В обычных условиях всё работает мгновенно, но стоит пользователю воспользоваться строкой поиска или функцией Alt+F, как любое перемещение по списку начинает вызывать «фризы» на несколько секунд. Рассмотрим детально, почему это происходит, и разберем эффективные способы устранения этой проблемы.
Проанализируем ситуацию. Когда мы используем директиву компиляции &НаСервере, платформа выполняет контекстный вызов. Это означает, что на сервер передаются абсолютно все данные формы: значения реквизитов, состояние элементов управления и, что самое важное, состояние ДинамическогоСписка.
Динамический список — это сложный объект, который хранит не только текст запроса, но и текущие пользовательские настройки: отборы, группировки, сортировки и параметры поиска. Если активен «Поиск» (который по своей природе отличается от жесткого отбора), система вынуждена выполнять следующие действия при каждом серверном вызове:
LIKE '%Текст%'. Это приводит к полному сканированию таблицы (Table Scan) в базе данных.В результате простая «пустая» процедура превращается в тяжелую операцию из-за неявных действий платформы по синхронизации состояния списка.
Самый простой и эффективный способ — исключить передачу данных динамического списка на сервер. Для этого заменим контекстный вызов &НаСервере на внеконтекстный &НаСервереБезКонтекста. Рассмотрим пример реализации.
Было (проблемный вариант):
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
ОбработатьДанныеТекущейСтроки(Элемент.ТекущиеДанные.Ссылка);
КонецПроцедуры
&НаСервере
Процедура ОбработатьДанныеТекущейСтроки(Ссылка)
// Здесь платформа тратит время на передачу всего контекста формы
// включая тяжелые настройки поиска
КонецПроцедуры
Стало (оптимизированный вариант):
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
Если Элемент.ТекущиеДанные <> Неопределено Тогда
ОбработатьДанныеБезКонтекста(Элемент.ТекущиеДанные.Ссылка);
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ОбработатьДанныеБезКонтекста(Знач Ссылка)
// На сервер передается только Ссылка. Контекст формы и
// состояние динамического списка остаются на клиенте.
// Фризы исчезают.
КонецПроцедуры
При использовании &НаСервереБезКонтекста платформа не пересылает данные динамического списка, и серверу не нужно заново вычислять поисковую выборку. Это сокращает время перехода в десятки раз.
Событие ПриАктивизацииСтроки коварно тем, что оно срабатывает очень часто: при каждом клике, при перемещении стрелками на клавиатуре и даже при программном обновлении списка. Если пользователь быстро пролистывает список, серверные вызовы могут «наслаиваться» друг на друга.
Рассмотрим, как внедрить небольшую задержку (дебаунсинг), чтобы серверный вызов происходил только тогда, когда пользователь зафиксировал курсор на определенной строке хотя бы на 0.2–0.5 секунды.
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
// Отключаем предыдущий обработчик, если пользователь нажал кнопку быстро
ОтключитьОбработчикОжидания("ВыполнитьСервернуюОперацию");
// Подключаем заново — вызов произойдет через 0.3 секунды покоя
ПодключитьОбработчикОжидания("ВыполнитьСервернуюОперацию", 0.3, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьСервернуюОперацию()
ДанныеСтроки = Элементы.Список.ТекущиеДанные;
Если ДанныеСтроки <> Неопределено Тогда
ВыполнитьПолезнуюРаботуНаСервере(ДанныеСтроки.Ссылка);
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьПолезнуюРаботуНаСервере(Ссылка)
// Логика обработки
КонецПроцедуры
Этот подход не только решает проблему тормозов при поиске, но и в целом снижает нагрузку на сервер при обычном пролистывании справочника.
Важно понимать, почему при обычном отборе (через НастройкиКомпоновкиДанных) тормозов нет, а при поиске через интерфейсную строку они появляются. Выясним причину:
Рекомендация: Если вы знаете, что пользователи будут часто искать данные по конкретной колонке (например, «Артикул»), лучше вывести над списком отдельное поле ввода для установки прямого Отбора, чем заставлять их использовать универсальный поиск.
Если специфика задачи всё же требует использования контекстного вызова (например, нужно изменить состояние других элементов формы), обратим внимание на следующие настройки:
Индексировать у полей, по которым чаще всего ведется поиск. Для строк ограниченной длины это критически важно.LEFT JOIN) с тяжелыми таблицами, то любая ревалидация поиска на сервере будет медленной. Постарайтесь максимально упростить основной запрос списка.Подведем итог: Главный виновник задержек — передача тяжелого состояния поиска внутри контекста формы. Переход на &НаСервереБезКонтекста в сочетании с ПодключитьОбработчикОжидания является «золотым стандартом» для разработки отзывчивых интерфейсов в 1С.