Как мы улучшили скорость работы табличных контролов библиотеки EMX Controls для Avalonia UI

от автора

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

В состав библиотеки EMX Controls входят сложные табличные контролы, такие как DataGridControl и TreeListControl (далее по тексту DataGrid и TreeList). Они сложны с точки зрения устройства внутренней инфраструктуры, поддерживаемых возможностей и сценариев работы, но довольны просты и логичны в отношении API и в обращении для конечного пользователя. Многие сценарии активируются при включении соответствующих опций. Однако есть две характеристики/поведения, которые важны для большинства пользователей, поскольку они влияют на комфорт работы с приложением. Это скорость отрисовки и плавность скроллинга.

Большой опыт разработки для разных .NET платформ в течение многих лет дает нам возможность строго подходить к оценке производительности визуальных компонентов. После первого релиза EMX Controls наша команда решила сосредоточиться на улучшении скорости работы наших контролов DataGrid и TreeList. И надо сказать, эти трудозатраты привели к значительным успехам. Так с последним мажорным обновлением мы существенно повысили производительность контролов. Время создания и отрисовки улучшилось почти в 3 раза, а скорость скроллинга — более чем в 2 раза. Ниже в этой статье позвольте мы приведем конкретные цифры и поделимся подходами, которые позволили нам добиться таких результатов.

Тестовое приложение

Чтобы объективно оценить улучшения производительности контролов, мы создали небольшое тестовое приложение на Avalonia 11.2.5. Вы можете его скачать и повторить тестирование на своей системе. Абсолютные цифры, скорее всего, будут другие, но в процентном отношении вы получите похожие с нашими результаты. Чтобы переключиться между старой и новой версией контролов, выберите версию контролов (1.0.98 или 1.1.112) в файле проекта.

Приложение создает контрол DataGrid и рисует его на весь экран. На нашей тестовой системе видимая часть контрола занимает 40 строк и 20 колонок. При измерении отрисовки контрола мы учитываем время, затраченное на инстанцирование контрола и дожидаемся завершения процесса лейаута, добавив команду в очередь Dispatcher’а. Мы производили несколько измерений, используя разные типы редакторов в ячейках контрола (текстовые редакторы, СheckBox’ы, выпадающие списки и т.д.). Каждое измерение повторяли по 5 раз и запоминали наименьшее значение. Компиляция в конфигурации Release и запуск без отладчика дали такие результаты:

Создание и отрисовка контрола

Версия 1.0.98

Версия 1.1.112

Текстовые редакторы

720 ms

250 ms

Чекбоксы

1550 ms

200 ms

Выпадающий список (ComboBox)

1100 ms

490 ms

Редакторы чисел (SpinEditor)

1120 ms

410 ms

Редакторы даты (DateEditor)

1060 ms

470 ms

Редактор с кнопками (ButtonEditor) (2 кнопки — с текстом и картинкой)

2190 ms

480 ms

Для измерения скорости скроллинга мы измеряли время, которое затрачивается на скроллинг таблицы с 10 000 объектов в источнике сверху вниз. При этом процесс скроллинга выполняется итеративно: мы изменяем смещение скроллбара на высоту видимой области и дожидаемся завершения процесса лейаута через команду в очереди Dispatcher’а. Этот тест дал такие результаты:

Скроллинг 10000 строк

Версия 1.0.98

Версия 1.1.112

Текстовые редакторы

9520 ms

4190 ms

Чекбоксы

13700 ms

2330 ms

Выпадающий список (ComboBox)

12600 ms

5100 ms

Редакторы чисел (SpinEditor)

13220 ms

5400 ms

Редакторы даты (DateEditor)

13320 ms

5400 ms

Редактор с кнопками (ButtonEditor) (2 кнопки — с текстом и картинкой)

14830 ms

3950 ms

Как видим, произведенные улучшения дают значительный прирост производительности.

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

Наши подходы к повышению производительности

Теперь позвольте рассказать о технических решениях, за счет которых получились такие результаты. Но в начале приведем общие рекомендации, которые могут быть полезными в любом Avalonia приложении:

  • Если есть большое количество перекрытых стилей с Selector’ами, имеет смысл упаковать их в ControlTheme.

    Из-за особенностей работы Selector’ов, каждый отдельный стиль в ресурсах приложения замедляет добавление любого элемента в дерево. Так, например, DataGrid в нашем тестовом приложении содержит 800 ячеек, каждая из которых состоит из несколько визуальных элементов. В результате, простое переписывание стилей на ControlTheme позволило уже ощутимо ускорить создание и первую отрисовку контрола.

  • Минимизируйте количество визуальных элементов и Selector’ов.

    Так в результате рефакторинга ControlTemplate’а ячейки в табличных контролах мы избавились от нескольких лишних Border’ов и уменьшили количество стилей для разных состояний элементов. Это дало заметный результат в нашем тестовом сценарии на 800 ячейках.

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

  • Размещение элементов в невидимой области вместо выставления видимости.

    DataGrid использует кастомную панель для виртуализации. Эта панель повторно использует контейнеры при скроллинге. Когда контейнер (ячейка) уходит из видимой области, ему выставляется позиция за пределами видимой области. Затем этот контейнер повторно используется для нового объекта в видимой области. Оказалось, что размещение ненужных в данный момент контейнеров в невидимой области работает быстрее, чем выставление им IsVisible=False.

  • Создание и использование полноценных редакторов в ячейках, только когда ячейка активируется.

    Стандартный контрол TextBox в Avalonia содержит в своем визуальном дереве больше 20 элементов. Если использовать его в каждой из 800 ячеек, отрисовка табличного контрола и скроллинг будут занимать неоправданно долгое время. Поэтому, чтобы улучшить производительность, полноценный редактор создается только для ячейки в момент ее активации. Когда фокус уходит из ячейки, редактор уничтожается. В неактивных ячейках показывается неинтерактивная «облегченная» версия редактора, которая не отличается по внешнему виду от настоящего редактора. Надо заметить, что мы изначально использовали элемент TextBlock вместо TextBox’а для текстовых ячеек в табличных контролах. В последнем большом обновлении мы максимально «облегчили» ячейки со встроенными СheckBox’ами. Теперь неактивные ячейки рисуют иконки вместо отображения полноценного CheckBox’а. Также подобной оптимизации подверглись и ячейки, где используются редакторы с кнопками (выпадающие списки, редакторы чисел, дат, и т.д.).

  • Использование кастомного TextBlock’а.

    Стандартный TextBlock при изменении текста всегда инициирует проход системы лейаута в Avalonia. В этом нет необходимости, когда TextBlock встраивается в ячейки таблицы, т.к. размер ячейки известен и не требует обновления лейаута элементов. В этом случае достаточно просто перерисовать текст. Ради этой основной оптимизации мы создали свой MxTextBlock, что дало самый большой вклад в ускорение скроллинга.

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

Теперь мы можем ответственно заявить, что наши табличные контролы — одни из самых быстрых для Avalonia. Некоторые наши тесты показывают, что они даже выигрывают и у многих табличных контролов для WPF от разных производителей.

Заключение

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

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

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

Выставка

16 апреля наша команда разработчиков EMX Controls будет на выставке ЭкспоЭлектроника 2025, которая стартует на день раньше. Приглашаем всех желающих к стенду Эремекс:

стенд № А3041, павильон №3, выставочный зал 13, МВЦ «Крокус Экспо».

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

Более подробная информация о программе выставки: Экосистема программных продуктов ЭРЕМЕКС на выставке ЭкспоЭлектроника 2025

Приходите, будем ждать.

Наши предыдущие статьи


ссылка на оригинал статьи https://habr.com/ru/articles/895016/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *