Ottimizzazione delle prestazioni: layout e progettazione

La progettazione dell'applicazione WPF può influire sulle prestazioni creando un sovraccarico non necessario nel calcolo del layout e nella convalida dei riferimenti agli oggetti. La costruzione di oggetti, soprattutto in fase di runtime, può influire sulle caratteristiche di prestazioni dell'applicazione.

Questo argomento offre utili suggerimenti per il miglioramento delle prestazioni in queste aree.

Layout

Il termine "passaggio layout" descrive il processo di misurazione e disposizione dei membri di una raccolta di elementi figlio derivata da un Paneloggetto derivato e quindi disegnarli sullo schermo. Il passaggio di layout è un processo molto complesso dal punto di vista matematico: più alto è il numero di elementi figlio presenti nella raccolta, maggiore è il numero di calcoli necessari. Ad esempio, ogni volta che un oggetto figlio UIElement nell'insieme modifica la posizione, può attivare un nuovo passaggio dal sistema di layout. Data la stretta correlazione tra le caratteristiche dell'oggetto e il comportamento del layout, è importante capire i tipi di eventi che possono richiamare il sistema di layout. Le prestazioni dell'applicazione risulteranno migliori se si riuscirà a ridurre al massimo le chiamate non necessarie al passaggio di layout.

Per ogni membro figlio di una raccolta vengono completati due passaggi: un passaggio di misurazione e uno di disposizione. Ogni oggetto figlio fornisce la propria implementazione sottoposta a override dei Measure metodi e Arrange per fornire il proprio comportamento di layout specifico. Nella forma più semplice, il layout è un sistema ricorsivo che fa sì che un elemento venga ridimensionato, posizionato e disegnato sullo schermo.

  • Un oggetto figlio UIElement inizia il processo di layout prima di tutto con le relative proprietà di base misurate.

  • Le proprietà dell'oggetto FrameworkElement correlate alle dimensioni, ad esempio Width, Heighte Margin, vengono valutate.

  • PanelViene applicata una logica specifica, ad esempio la Dock proprietà dell'oggetto DockPanelo la Orientation proprietà dell'oggetto StackPanel.

  • Il contenuto viene disposto, o posizionato, dopo la misurazione di tutti gli oggetti figlio.

  • La raccolta di oggetti figlio viene disegnata sullo schermo.

Il passaggio di layout viene nuovamente richiamato qualora si verifichi una delle azioni seguenti:

  • Un oggetto figlio viene aggiunto alla raccolta.

  • Un LayoutTransform oggetto viene applicato all'oggetto figlio.

  • Il UpdateLayout metodo viene chiamato per l'oggetto figlio.

  • Se viene apportata una modifica al valore di una proprietà di dipendenza contrassegnata con metadati che incidono sul passaggio di misurazione o disposizione.

Usare il pannello più efficiente, se possibile

La complessità del processo di layout si basa direttamente sul comportamento di layout degli Panelelementi derivati da . Ad esempio, un Grid controllo o StackPanel fornisce molte più funzionalità rispetto a un Canvas controllo . All'aumento delle funzionalità corrisponde, tuttavia, un maggiore dispendio in termini di prestazioni. Tuttavia, se non è necessaria la funzionalità fornita da un Grid controllo, è consigliabile usare le alternative meno costose, ad esempio un Canvas pannello personalizzato o .

Per altre informazioni, vedere Cenni preliminari sugli elementi Panel.

Aggiornare anziché sostituire una proprietà RenderTransform

È possibile aggiornare un oggetto Transform anziché sostituirlo come valore di una RenderTransform proprietà. Questa possibilità può essere attuata soprattutto negli scenari con animazioni. Aggiornando un oggetto esistente Transform, si evita di avviare un calcolo di layout non necessario.

Compilare la struttura ad albero dall'alto in basso

Quando si aggiunge o si rimuove un nodo dall'albero logico, le convalide di proprietà vengono annullate sull'elemento padre e su tutti gli elementi figlio del nodo. Di conseguenza, è sempre consigliabile seguire un pattern di costruzione dall'alto in basso per evitare il costo di annullamenti di convalide non necessari su nodi già convalidati. La tabella seguente mostra la differenza nella velocità di esecuzione tra la creazione di un albero dall'alto verso il basso rispetto al basso verso l'alto, dove l'albero è di 150 livelli profondi con un singolo TextBlock e DockPanel a ogni livello.

Azione Compilazione della struttura ad albero (in ms) Rendering: include la compilazione della struttura ad albero (in ms)
Dal basso in alto 366 454
Dall'alto in basso 11 96

L'esempio di codice seguente illustra come creare una struttura ad albero dall'alto in basso.

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;
    }
}
Private Sub OnBuildTreeTopDown(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim textBlock As New TextBlock()
    textBlock.Text = "Default"

    Dim parentPanel As New DockPanel()
    Dim childPanel As DockPanel

    myCanvas.Children.Add(parentPanel)
    myCanvas.Children.Add(textBlock)

    For i As Integer = 0 To 149
        textBlock = New TextBlock()
        textBlock.Text = "Default"
        parentPanel.Children.Add(textBlock)

        childPanel = New DockPanel()
        parentPanel.Children.Add(childPanel)
        parentPanel = childPanel
    Next i
End Sub

Per altre informazioni sull'albero logico, vedere Strutture ad albero in WPF.

Vedi anche