Оптимизация производительности: Разметка и разработка
Разработка приложения WPF может повлиять на его производительность в результате создания ненужных служебных данных при вычислении макета и проверки ссылок на объекты. Конструирование объектов, особенно во время выполнения, может повлиять на характеристики производительности приложения.
В этом разделе даются рекомендации по производительности в этих областях.
Макет
Термин «проход разметки» описывает процесс измерения и упорядочения объекта Panel-коллекции объектов производного объекта дочерних элементов, и затем рисование их на экране. Проход разметки представляет собой процесс интенсивной математической нагрузки: чем больше число дочерних объектов в коллекции, тем больше требуется вычислений. Например, каждый раз, когда дочерний элемент UIElement объекта в коллекции изменяет свое положение, он имеет возможность запустить новый проход системы макета. Из-за разрыва отношения между характеристиками объекта и поведением разметки важно понимать тип событий, которые могут запустить систему разметки. Приложение будет выполняться лучше, если уменьшить, насколько возможно, ненужные вызовы прохода разметки.
Система разметки выполняет два прохода для каждого дочернего члена в коллекции: проход измерений и проход компоновки. Каждый дочерний объект предоставляет свою собственную переопределенную реализацию из Measure и Arrange методы, чтобы обеспечить собственное поведение конкретного макета. В самом простом случае макет является рекурсивной системой, в процессе которой программа изменяет размер и расположение элемента и отображает его на экране.
Дочерний элемент UIElement объект начинает процесс разметки первым, задав его основные измеряемые свойства.
Объекта FrameworkElement свойства, относящиеся к размеру, такие как Width, Height, и Margin, вычисляются.
Panel-применяется специальная логика, такие как Dock свойство DockPanel, или Orientation свойство StackPanel.
Содержимое компонуется или размещается после всех дочерних объектов, которые были измерены.
На экране отображается коллекция дочерних объектов.
Процесс прохода разметки вызывается снова при возникновении любого из следующих событий.
Дочерний объект добавляется в коллекцию.
Объект LayoutTransform применяется к дочернему объекту.
UpdateLayout Метод вызывается для дочернего объекта.
При изменении значения свойства зависимости, которое помечено метаданными, влияющими на проход измерения и компоновки.
Используйте наиболее эффективную панель там, где возможно
Сложность прохода разметки непосредственно основана на поведения Panel-используемых элементов, производных. Например Grid или StackPanel элемент управления предоставляет гораздо больше возможностей, чем Canvas элемента управления. Ценой этого значительного увеличения функциональности является увеличение затрат производительности. Тем не менее если не требуется функциональность, Grid предоставляет элемент управления, следует использовать менее затратные варианты, например Canvas или настраиваемую панель.
Дополнительные сведения см. в разделе Общие сведения о панелях.
Обновление вместо замены RenderTransform
Можно обновить Transform вместо замены его в качестве значения RenderTransform свойство. Это особенно актуально в скриптах, включающих анимацию. Обновление существующего Transform, вы избегаете инициирования ненужных вычислений разметки.
Построение дерева сверху вниз
При добавлении или удалении узла из логического дерева свойство аннулирования вызывается на родительском узле и всех дочерних узлах. В результате всегда требуется следовать шаблону структуры сверху вниз, во избежание ненужных аннулирований на узлах, которые уже были проверены. В следующей таблице показаны разница в скорости выполнения между построением дерева сверху вниз или снизу вверх, где в дереве 150 уровней с одним TextBlock и DockPanel на каждом уровне.
Действие | Построение дерева (мс) | Отрисовки — включает построение дерева (мс) |
---|---|---|
Снизу вверх | 366 | 454 |
Сверху вниз | 11 | 96 |
В следующем примере кода демонстрируется создание дерева сверху вниз.
private void OnBuildTreeTopDown(object sender, RoutedEventArgs e)
{
TextBlock textBlock = new TextBlock();
textBlock.Text = "Default";
DockPanel parentPanel = new DockPanel();
DockPanel childPanel;
myCanvas.Children.Add(parentPanel);
myCanvas.Children.Add(textBlock);
for (int i = 0; i < 150; i++)
{
textBlock = new TextBlock();
textBlock.Text = "Default";
parentPanel.Children.Add(textBlock);
childPanel = new DockPanel();
parentPanel.Children.Add(childPanel);
parentPanel = childPanel;
}
}
Дополнительные сведения о логическом дереве см. в разделе Деревья в WPF.