Share via


Pianificazione delle prestazioni

Gli utenti si aspettano che le app rispondano velocemente e risultino naturali, oltre a non consumare eccessivamente la batteria. Tecnicamente, le prestazioni non sono un requisito funzionale, ma considerare le prestazioni come una funzionalità ti permetterà di essere all'altezza delle aspettative dei tuoi utenti. Specificare gli obiettivi e misurarli sono fattori chiave. Stabilisci quali sono gli scenari cruciali per le prestazioni e definisci il concetto di buone prestazioni. Quindi esegui misurazioni sin dalle prima fasi e con una frequenza sufficiente per tutto il ciclo di vita del progetto per essere certo di raggiungere i tuoi obiettivi.

Definizione degli obiettivi

L'esperienza utente è un metodo di base per definire il livello delle prestazioni. Il tempo di avvio di un'app può influire sulla percezione dell'utente delle relative prestazioni. Un utente potrebbe considerare eccellente un tempo di avvio inferiore a un secondo per un'app, buono se inferiore a 5 secondi e scarso se superiore a 5 secondi.

Altre metriche hanno un impatto meno evidente sull'esperienza utente, ad esempio la memoria. Le probabilità che un'app venga terminata mentre è sospesa o inattiva sono maggiori se il consumo di memoria è elevato. È una regola generale che un utilizzo elevato della memoria peggiora l'esperienza per tutte le app nel sistema, quindi è ragionevole porsi un obiettivo per l'uso della memoria. Prendi in considerazione le dimensioni approssimative dell'app percepite dagli utenti: piccole, medie o grandi. Le aspettative per le prestazioni saranno correlate a questa percezione. Ad esempio, potresti volere che un'app di piccole dimensioni con pochi contenuti multimediali usi meno di 100 MB di memoria.

È preferibile impostare un obiettivo iniziale e quindi modificarlo in seguito, piuttosto che non prefissarsi alcun obiettivo. Gli obiettivi per le prestazioni dell'app devono essere specifici e misurabili e rientrano in tre categorie: quanto tempo occorre agli utenti o all'app per completare le attività (tempo), la frequenza e la continuità con cui l'app viene ridisegnata in risposta all'interazione con l'utente (fluidità) e l'uso oculato delle risorse di sistema, inclusa la carica della batteria (efficienza).

Inserimento ore

Valuta gli intervalli di tempo trascorso accettabili (classi di interazione) impiegati dagli utenti per completare le loro attività nella tua app. A ogni classe di interazione assegna un'etichetta, la valutazione percepita dell'utente e la durata ideale e massima. Ecco alcuni suggerimenti.

Etichetta della classe di interazione Percezione dell'utente Ideale Massimo Esempi
Veloce Ritardo appena percepibile 100 millisecondi 200 millisecondi Visualizzazione della barra dell'app, pressione di un pulsante (prima risposta)
Typical (Tipica) Interazione relativamente veloce 300 millisecondi 500 millisecondi Ridimensionamento, zoom semantico
Reattività Interazione non veloce, ma con percezione di risposta 500 millisecondi 1 secondo Passaggio a una pagina diversa, ripresa dell'app da uno stato sospeso
Launch Esperienza di contesa 1 secondo 3 secondi Primo avvio dell'app o riavvio dopo una precedente chiusura
Continuo Percezione di assenza di risposta 500 millisecondi 5 secondi Download di un file da Internet
Bloccata Tempi lunghi, possibile abbandono da parte dell'utente 500 millisecondi 10 secondi Installazione di più app da Store

 

È ora possibile assegnare classi di interazione agli scenari di prestazioni dell'app. È possibile assegnare il riferimento temporale dell'app, una parte dell'esperienza utente e una classe di interazione a ogni scenario. Ecco alcuni suggerimenti per un'app di esempio per cibo e ristorazione.

ScenarioFaseEsperienza utenteClasse di interazione
Passaggio alla pagina della ricetta Prima rispostaAnimazione di transizione di pagina avviataVeloce (100 - 200 millisecondi)
ReattivitàElenco degli ingredienti caricato, senza immaginiReattiva (500 millisecondi - 1 secondo)
Visualizzazione completaTutto il contenuto caricato, incluse le immaginiContinua (500 millisecondi - 5 secondi)
Ricerca di una ricettaPrima rispostaPulsante di ricerca sceltoVeloce (100 - 200 millisecondi)
Visualizzazione completaElenco dei titoli delle ricette locali visualizzatoTipica (300 - 500 millisecondi)

Se visualizzi contenuto live, dovrai prendere in considerazione anche gli obiettivi di aggiornamento del contenuto. L'obiettivo è aggiornare il contenuto a distanza di pochi secondi? Oppure è accettabile un'esperienza utente con un aggiornamento del contenuto a distanza di alcuni minuti o ore o persino una volta al giorno?

Dopo aver specificato gli obiettivi potrai affrontare in modo migliore il processo di test, analisi e ottimizzazione della tua app.

Fluidità

Gli obiettivi di fluidità misurabili specifici per la tua app potrebbero includere:

  • Assenza di interruzioni e riavvii per l'aggiornamento dello schermo (glitch).
  • Rendering delle animazioni a 60 fotogrammi al secondo (FPS).
  • Durante lo scorrimento, l'app presenta 3-6 pagine di contenuto al secondo.

Efficienza

Gli obiettivi di efficienza misurabili specifici per la tua app potrebbero includere:

  • Per il processo della tua app, la percentuale di utilizzo della CPU è sempre uguale o minore di N e l'uso della memoria in MB è sempre uguale o minore di M.
  • Quando l'app è inattiva, N e M sono pari a zero per il processo dell'app.
  • La tua app può essere usata attivamente per X ore con alimentazione a batteria. Quando l'app è inattiva, il dispositivo dovrebbe mantenersi carico per Y ore.

Progettare l'app per le prestazioni

È ora possibile usare gli obiettivi di prestazioni stabiliti per ottimizzare la progettazione dell'app. Ritornando all'esempio dell'app per cibo e ristorazione, dopo che l'utente passa alla pagina della ricetta, può scegliere di aggiornare gli elementi in modo incrementale in modo che il nome della ricetta venga visualizzato per primo, seguito dagli ingredienti e poi dalle immagini. Questo consente di mantenere l'interfaccia utente reattiva e fluida durante lo scorrimento, posticipando l'esecuzione del rendering alla massima fedeltà al momento in cui le interazioni rallentano fino al punto da permettere al thread dell'interfaccia utente di recuperare. Ecco qualche altro aspetto da considerare.

INTERFACCIA UTENTE

  • Ottimizzare i temi di analisi e caricamento e l'efficienza della memoria per ogni pagina dell'interfaccia utente dell'app (in particolare la pagina iniziale) ottimizzando il markup XAML. In sintesi, posticipare il caricamento dell'interfaccia utente e del codice fino a quando non è necessario.
  • Per ListView e GridView rendere tutti gli elementi delle stesse dimensioni e usare il maggior numero possibile di tecniche di ottimizzazione di ListView e GridView.
  • Dichiarare l'interfaccia utente sotto forma di markup, che il framework può caricare e riutilizzare in blocchi, invece di costruirla in modo imperativo nel codice.
  • Ritarda la creazione degli elementi dell'interfaccia utente fino a quando non servono all'utente. Vedi l'attributo x:Load.
  • Preferire le transizioni del tema e le animazioni alle animazioni con storyboard. Per altre info, vedere Panoramica delle animazioni. Ricordare che le animazioni con storyboard richiedono aggiornamenti costanti dello schermo e tengono attive la CPU e la pipeline degli elementi grafici. Per un miglior uso della batteria, evitare l'esecuzione di animazioni se l'utente non interagisce con l'app.
  • Le immagini caricate dovrebbero essere caricate con dimensioni appropriate per la visualizzazione in cui vengono presentate, tramite il metodo GetThumbnailAsync.

CPU, memoria e alimentazione

  • Pianificare le operazioni con priorità inferiore per l'esecuzione su thread e/o core con priorità inferiore. Vedere Programmazione asincrona, la proprietà Dispatcher e la classe CoreDispatcher.
  • Ridurre al minimo il footprint di memoria dell'app rilasciando le risorse onerose (come gli elementi multimediali) in fase di sospensione.
  • Ridurre al minimo il working set del codice.
  • Evitare perdite di memoria annullando la registrazione di gestori di eventi e dereferenziando gli elementi dell'interfaccia utente ogni volta possibile.
  • Nell'ottica di un uso ottimale della batteria, ridurre al minimo la frequenza di polling dei dati e di richiesta dei dati a un sensore oppure pianificare le operazioni sulla CPU quando è inattiva.

Accesso ai dati

  • Se possibile, usare la prelettura del contenuto. Per il caricamento in background automatico, vedere la classe ContentPrefetcher. Per il caricamento in background manuale, vedere lo spazio dei nomi Windows.ApplicationModel.Background e la classe MaintenanceTrigger.
  • Se possibile, memorizzare nella cache il contenuto che richiede molte risorse per l'accesso. Vedere le proprietà LocalFolder e LocalSettings.
  • Per i mancati riscontri nella cache, visualizzare un'interfaccia utente segnaposto il prima possibile per indicare che l'app sta ancora caricando il contenuto. Gestire la transizione dal contenuto segnaposto al contenuto attivo in modo da non disturbare l'utente. Ad esempio, non cambiare la posizione del contenuto sotto il dito o il puntatore dell'utente mentre l'app carica il contenuto attivo.

Avvio e ripresa dell'app

Interfaccia utente adattiva e orientamento

  • Usare la classe VisualStateManager.
  • Eseguire immediatamente solo le operazioni necessarie, posticipando quelle più onerose in termini di risorse. L'app ha a disposizione tra 200 e 800 millisecondi per completare le operazioni prima che l'utente visualizzi l'interfaccia utente in stato ritagliato.

Una volta definiti gli elementi di progettazione correlati alle prestazioni, è possibile iniziare a scrivere il codice dell'app.

Instrumentare le app per le prestazioni

Durante lo sviluppo, aggiungere codice per registrare messaggi ed eventi in corrispondenza di determinati punti dell'esecuzione dell'app. Successivamente, durante il test dell'app, è possibile usare strumenti di profilatura come Windows Performance Recorder e Windows Performance Analyzer (entrambi inclusi in Windows Performance Toolkit) per creare e visualizzare un report sulle prestazioni dell'app. I messaggi e gli eventi contenuti in questo report consentono di analizzare più facilmente i risultati.

La piattaforma UWP (Universal Windows Platform) fornisce API di registrazione, basate su Event Tracing for Windows (ETW), che insieme offrono una soluzione avanzata per la registrazione e la traccia di eventi. Le API, che fanno parte dello spazio dei nomi Windows.Foundation.Diagnostics, includono le classi FileLoggingSession, LoggingActivity, LoggingChannel e LoggingSession.

Per registrare un messaggio nel report in corrispondenza di un punto specifico dell'esecuzione dell'app, creare un oggetto LoggingChannel e quindi chiamare il relativo metodo LogMessage come nell'esempio seguente.

// using Windows.Foundation.Diagnostics;
// ...

LoggingChannel myLoggingChannel = new LoggingChannel("MyLoggingChannel");

myLoggingChannel.LogMessage(LoggingLevel.Information, "Here' s my logged message.");

// ...

Per inserire nel report gli eventi di avvio e arresto relativi a un periodo di tempo specifico durante l'esecuzione dell'app, creare un oggetto LoggingActivity e quindi chiamare il relativo costruttore LoggingActivity come nell'esempio seguente.

// using Windows.Foundation.Diagnostics;
// ...

LoggingActivity myLoggingActivity;

// myLoggingChannel is defined and initialized in the previous code example.
using (myLoggingActivity = new LoggingActivity("MyLoggingActivity"), myLoggingChannel))
{   // After this logging activity starts, a start event is logged.
    
    // Add code here to do something of interest.
    
}   // After this logging activity ends, an end event is logged.

// ...

Vedere anche l'esempio di registrazione.

Dopo avere instrumentato l'app, è possibile testarne e misurarne le prestazioni.

Testare e misurare i risultati rispetto agli obiettivi di prestazioni

Parte del piano per le prestazioni dovrebbe prevedere la definizione di tutti i punti in cui verranno misurate le prestazioni durante lo sviluppo. Questo serve a scopi diversi, a seconda del fatto che la misurazione venga effettuata in fase di prototipo, sviluppo o distribuzione. La misurazione delle prestazioni durante le fasi iniziali del prototipo può essere incredibilmente preziosa, quindi si consiglia di farlo non appena è disponibile codice che esegue operazioni significative. Le misurazioni iniziali danno un'idea chiara di quali siano i costi più importanti nell'app e possono determinare le decisioni di progettazione. Il risultato sono app ad alte prestazioni e scalabilità elevata. È in genere più costoso modificare i progetti nelle fasi avanzate piuttosto che all'inizio. Se si misurano le prestazioni in una fase avanzata del ciclo del prodotto, ci si potrebbe ritrovare ad apportare correzioni all'ultimo minuto oppure a ottenere prestazioni scarse.

Usare le tecniche e gli strumenti seguenti per valutare le prestazioni dell'app rispetto agli obiettivi originali.

  • Ripetere il test con tutte le configurazioni hardware, inclusi PC all-in-one e desktop, portali, ultrabook, tablet e altri dispositivi mobili.
  • Eseguire i test su un'ampia gamma di dimensioni dello schermo. Nonostante dimensioni dello schermo maggiori consentano di visualizzare più contenuto, la visualizzazione di tutto questo contenuto può influire negativamente sulle prestazioni.
  • Eliminare quante più variabili di test possibile.
    • Disattivare le app in background nel dispositivo di test. A tale scopo, in Windows selezionare Impostazioni dal menu Start >Personalizzazione>Schermata di blocco. Selezionare ogni app attiva e scegliere Nessuna.
    • Compilare l'app in codice nativo nella configurazione di rilascio prima di distribuirla nel dispositivo di test.
    • Per garantire che la manutenzione automatica non influisca sulle prestazioni del dispositivo di test, attivarla manualmente e attendere il completamento. In Windows cercare Sicurezza e manutenzione nel menu Start. Nell'area Manutenzione, in Manutenzione automatica, selezionare Avvia manutenzione e aspettare che lo stato diventi Manutenzione in corso.
    • Eseguire l'app più volte per eliminare le variabili di test casuali e ottenere misurazioni omogenee.
  • Eseguire test per gli scenari con potenza ridotta. Il dispositivo degli utenti potrebbe essere decisamente meno potente del computer di sviluppo. Windows è stato progettato anche tenendo conto dei dispositivi a bassa potenza, come i dispositivi mobili. Le app eseguite sulla piattaforma dovrebbero garantire buone prestazioni anche in questi dispositivi. Ci si può aspettare realisticamente che un dispositivo poco potente sia circa quattro volte più lento di un computer desktop, pertanto stabilire gli obiettivi di conseguenza.
  • Usare una combinazione di set di strumenti come Microsoft Visual Studio e Windows Performance Analyzer per misurare le prestazioni dell'app. Visual Studio è progettato per fornire un'analisi incentrata sull'app, ad esempio il collegamento del codice sorgente. Windows Performance Analyzer è progettato per fornire un'analisi incentrata sul sistema, ad esempio info di sistema, info su eventi di modifica tramite tocco e info sul costo dell'I/O su disco e della GPU (Graphics Processing Unit). Entrambi questi strumenti offrono funzionalità per l'acquisizione e l'esportazione di tracce e consentono di riaprire tracce condivise e tracce dopo che l'applicazione è terminata.
  • Prima di inviare l'app allo Store per la certificazione, assicurati di includere nei piani di test i test case correlati alle prestazioni, come descritto nella sezione "Test delle prestazioni" di Test del Kit di certificazione app Windows e nella sezione "Prestazioni e stabilità" di Test case per le app UWP.

Per altre info, vedere queste risorse e gli strumenti di profilatura.

Rispondere ai risultati dei test delle prestazioni

Dopo avere analizzato i risultati dei test delle prestazioni, stabilire se sono necessarie modifiche, ad esempio:

  • Occorre modificare una o più delle decisioni inerenti la progettazione dell'app oppure ottimizzare il codice?
  • Occorre aggiungere, rimuovere o modificare uno o più elementi di strumentazione nel codice?
  • Occorre modificare uno o più obiettivi di prestazioni?

Se sono necessarie modifiche, eseguirle e poi tornare alla fase di strumentazione o test e ripetere.

Ottimizzazione

Ottimizzare solo i percorsi del codice critici per le prestazioni nell'app, ovvero quelli a cui viene dedicata la maggior parte del tempo. La profilatura indicherà quali sono. Si dovrà spesso accettare dei compromessi tra creare software conforme alle procedure di progettazione ottimali e scrivere codice con prestazioni di livello elevato. Generalmente è meglio dare la priorità alla produttività dello sviluppatore e a un buon progetto software nelle aree in cui le prestazioni non sono determinanti.