Приложение Flex с большим количеством объектов пользовательского интерфейса == медленно? - PullRequest
3 голосов
/ 10 июня 2009

Я создаю свой первый пользовательский компонент Flex во Flex 3. Это таблица данных, основанная на классе контейнера Grid, с простой текстовой меткой в ​​каждой ячейке. (DataGrid и AdvancedDataGrid не были подходящими отправными точками для моих нужд.) Компонент работает довольно хорошо с использованием небольших таблиц, но я попытался провести стресс-тестирование с использованием таблицы большего размера и был разочарован результатами.

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

Эта «большая» таблица выборок содержит чуть более 7000 ячеек. Это довольно крупно, но все же на 1-2 порядка меньше, чем самое большое, что мне нужно. В стандартной структуре Grid основная часть компонента состоит из Grid с 400 GridRows по 16 GridItems каждый, а также с несколькими другими более мелкими вспомогательными Grid.

Как только таблица рендерится, я найду следующее:

  • События, связанные с мышью, запускаются медленно. В частности, у меня есть обработчики событий rollOver / rollOut, зарегистрированные в каждой ячейке таблицы, чтобы я мог выделить ячейку под указателем. На маленьком столе я мог очень быстро навести указатель мыши на стол, и подсветка следовала бы за указателем в режиме реального времени. При использовании таблицы большего размера выделение становится очень резким, оно меняется только примерно два раза в секунду, пропуская множество ячеек.
  • Если я наведу курсор мыши на компонент и оставлю его там, мой ЦП будет привязан (в любом случае, к одному ядру процессора) и останется таким до тех пор, пока я не покину компонент, пока он не перейдет в режим ожидания. На данный момент мой компонент ничего не делает.

Такое ощущение, что Flex просто не может масштабироваться для поддержки таких больших деревьев компонентов. Мне страшно представить, как он будет вести себя с 100 000 клеток. Возможно, я выдвигаю Grid за пределы его предполагаемого использования, но наличие объекта на ячейку таблицы не кажется необоснованной моделью, и ~ 14 000 объектов в дереве (GridItem и Label на ячейку) кажутся довольно скромными.

Мне еще предстоит получить полезные данные из профилировщика FlexBuilder; Я работаю над этим. На данный момент, мои самые большие вопросы:

  • Действительно ли я раздвигаю пределы Flex с помощью этого скромного теста?
  • Является ли мой подход к этому компоненту совершенно неосновным?

Я запускаю это на Flash Player 9 под Firefox на WinXP.

Ответы [ 5 ]

7 голосов
/ 10 июня 2009

Да, Flex не предназначен для поддержки очень большого количества компонентов, хорошо известно, что вы должны минимизировать количество компонентов и не использовать ненужные функции (например, DisplayObject вместо Canvas, если вы не нужны дополнительные функции).

Неразумно точно отражать ваши данные отображаемыми объектами. Объекты DisplayObject (и связанные с ними классы) относительно тяжелые, и вам нужно контролировать, сколько из них у вас есть.

Я бы сказал, что масштаб, в котором вы работаете, с 1000+ Cells и слушателем событий для каждого, определенно достигнет пределов Flex.

Я думаю, вы должны лучше взглянуть на свой подход и архитектуру. Я предполагаю, что вы не отображаете все 1000+ элементов одновременно, возможно, вы должны использовать пейджинг и отображать 100ish для каждого экрана, с предыдущими / следующими кнопками, чтобы перейти на другую страницу. Вы также можете рассмотреть возможность динамического добавления и удаления строк с помощью пользовательской полосы прокрутки, имитирующей эффект прокрутки. Это гораздо сложнее сделать.

6 голосов
/ 24 мая 2011

Мальчик, кажется, мы можем написать книгу на эту тему. Или хотя бы главу. Мы узнали немало вещей в этой области, когда разрабатывали наши продукты.

Итог - да, Flex замедлится, когда вы добавите более 1000 «вещей» на экран. Вот несколько пунктов и несколько повторений того, что уже упоминалось (просто для краткости)

1) Всегда рисуйте только то, что видно. Ханс Мюллер (Hans Muller), архитектор новой Spark DataGrid, отлично работает над ViewPorts. http://hansmuller -flex.blogspot.com / 2009/06 / введение к видовым-и-scrolling.html . Таким образом, создайте достаточно «ячеек», чтобы заполнить видимую область, и в основном перерабатывайте их по мере прокрутки пользователем.

2) Recycle, recycle, recycle: В дополнение к вышесказанному, когда пользователь выполняет прокрутку, вам, очевидно, придется перерабатывать ячейки, которые теперь не видны, чтобы показать те, которые находятся на виду. Здесь есть несколько вещей, которые мы выучили трудным путем :-) -> Вместо того, чтобы располагать и создавать новые ячейки, либо используйте переопределение, либо используйте репозиционирование (предпочитайте репозиционирование)

Что это означает: скажем, у вас есть сетка 10X10 (видимая), показывающая поставщика данных 100X100. Когда пользователь прокручивает до ячеек 20X20, самый быстрый способ будет установить X и Y существующих ячеек на новые местоположения, а затем вызвать набор данных для каждого. Мы использовали репертуар раньше, потому что наш сценарий представлял собой серию связанных контейнеров, поэтому это может не относиться к вам. Но суть - мы просто перемещаем «ряды» вокруг видимой области. Таким образом, создание и уничтожение будут выполняться медленнее, удаление и добавление в список экранных объектов будет выполняться быстрее, а простое перемещение (x, y) будет самым быстрым.

3) Выберите то, что унаследовано от вас: Flex SDK - это чудовище. Так что выбирайте свой базовый класс "ячейки" с умом. Например, DataGrids SDK имеют облегченный рендер, который наследуется от UITextField (Halo), в отличие от Label. Даже UIComponent будет тяжелым в определенных сценариях. Посмотрите asdocs для UIComponent и посмотрите, нужно ли вам все там, иначе рассмотрите возможность наследования от дальнейшей иерархии.

4) Вычисления кеша: делайте это последним в цикле разработки. Как только вы закончите с функцией, запустите Flex Profiler. Определите самые длительные методы и наиболее часто вызываемые методы. Мы всегда делаем это, когда выпускаем, потому что всегда есть улучшения, которые нужно сделать. Когда вы разрабатываете визуальный компонент, требуется много математики, а слишком большое количество вычислений замедляет процесс.

5) Убедитесь, что вы профилируете для памяти: несвязанные прослушиватели событий, мошеннические ссылки на объекты и т. Д. Снижают производительность. Flex profiler - отличный инструмент для борьбы с этим, поэтому обязательно используйте его.

У нас есть несколько хороших ссылок здесь: http://www.flexicious.com/resources/Ultimate/Docs/LargeDataset.htm?

Надеюсь, это поможет!

3 голосов
/ 10 июня 2009

Если вы посмотрите на любой элемент управления на основе списков в среде Flex, вы увидите, что они широко используют средства визуализации элементов, которые были переработаны. Таким образом, DataGrid с отображаемыми 20 строками создает только около 22 средств визуализации и перерабатывает их при прокрутке списка. Вот почему DataGrid может хранить тысячи записей и при этом иметь довольно высокую производительность. Я рекомендую вам ознакомиться с серией статей Питера Энта о средствах визуализации элементов и взглянуть на ListBase / List и некоторые связанные классы, чтобы понять, как создать нечто подобное:

http://weblogs.macromedia.com/pent/archives/2008/03/itemrenderers_p.html

1 голос
/ 10 июня 2009

Не видя своего кода и не зная точно, что вы пытаетесь сделать ... определенно кажется, что вы раздвигаете пределы Flex, вставляя столько данных в среду сразу.

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

Вы можете попробовать предоставить службы данных (Java, .NET и т. Д.) Для управления данными в вашем приложении. Затем вы бы пролистали данные так, чтобы фреймворк работал только с 200 - 300+ элементами одновременно.

0 голосов
/ 12 июня 2009

В flex, если вы используете событие перемещения мыши для перерисовки чего-либо .. Возможно, вы испытали очень медленный рендеринг.

например:

this.addEventListener (MouseEvent.MOUSE_MOVE, redraw);

и

public function redraw(anything:Object=null):void{
        //draw something here
            this.graphics.clear();
            this.graphics.lineStyle(3, 0x000000);
            this.graphics.moveTo(startPoint.x, startPoint.y);
            this.graphics.lineTo(endPoint.x, endPoint.y);
            this.scaleTextInput.x = centerPoint.x;
            this.scaleTextInput.y = centerPoint.y;

    }

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

Решение:

Вместо этого использовать событие Event.ENTER_FRAME? Хотя это более ресурсоемко, чем событие перемещения мыши, вы должны получать значительно больше обновлений в секунду, что позволяет мыши выглядеть более отзывчивой для пользователя:

Например:

this.addEventListener (Event.ENTER_FRAME, перерисовать); вместо

this.addEventListener (MouseEvent.MOUSE_MOVE, redraw);

и ты готов идти .. Счастливое сгибание

Подробнее о: http://www.deepakdhakal.com

...