Liste e performance

Torno a tediarvi in questo mio blog dopo qualche giorno (se non qualche settimana) di latitanza, ma sono stato relativamente indaffarato. Abbiamo proprio in questi giorni aggiornato sia trackFinger che trackSlate alla versione 1.2.5, ed entrambe portano diversi miglioramenti, ma di questo vi parlerò un’altra volta.

trackSlate_promoVideo.p07

Oggi mi concentrerei su qualcosa che ha a che vedere con il futuro di trackSlate, il futuro prossimo, perché annunceremo un importante miglioria, se non proprio qualcosa che trasformerà la natura stessa dell’applicazione. Ma per farlo vorrei raccontarvi un po’ quello che sta avvenendo “sotto il cofano”, e vi chiedo un attimo di pazienza…

Aprite una qualsiasi app sul vostro dispositivo mobile, la probabilità che questa applicazione vi mostri una lista di cose è decisamente molto alta. Pensate a Twitter: qualsiasi applicazione che si interfaccia con l’uccello (evitate di fare battute) mostra essenzialmente una lista di tweet.

New-Twitter-App-iPhone-Android

Facebook è altresì una lista di post e di notizie. Insomma, a parte alcune eccezioni, quasi tutte le applicazioni devono mostrare una lista di qualcosa, che sia una lista della spesa, una lista di eventi, una lista di notizie, una lista di documenti… Sempre di liste si tratta.

Generalmente queste liste sono realizzate in HTML e scaricate dinamicamente da Internet. Vi sarà capitato, qualche volta, grazie alla connessione lenta, di vedere effettivamente come è strutturato il flusso di notizie di Facebook: una serie di testi non formattati. La formattazione arriva mediante del codice CSS, oltre a tutte le immagini che consentono di rappresentare meglio gli oggetti mostrati.

trackFinger mostra delle liste in due occasioni: nella schermata di lista dei progetti

tf_promo_pct01

e nella schermata di lista delle tracce di ogni progetto.

tf_promo_v12

Realizzare queste liste è stato probabilmente il compito più difficile da programmare per il sottoscritto quando ha iniziato a sviluppare questa applicazione. Perché? Semplicemente perché, dato che io utilizzo una sistema di sviluppo non nativo (nella fattispecie Adobe Director) non ho accesso a tutte le potenzialità del sistema sottostante, soprattutto quella che consente di visualizzare il codice HTML, delle tabelle HTML per essere più precisi, in un riquadro.

Ho dovuto, dunque, scrivere il codice che consente dimostrare delle liste di testi (e anche di immagini, se considerate le icone presenti in ogni riga nella lista delle tracce).

IMG_0009

Dato che Director, per qualche motivo a me ignoto, gestisce male i testi in iOS 7, ho dovuto fare uso di oggetti Flash per queste liste, per cui quando vedete queste schermate, il riquadro bianco con gli elenchi è essenzialmente un oggetto Flash comandato da Director. Ogni riga di questo oggetto Flash è un movie clip che viene duplicato ogni volta, e le informazioni testuali presenti i  ogni riga vengono modificatae mediante Director cambiando delle variabili in flash.

La cosa, di per sé, non sarebbe nemmeno così complicata se non per via di due problemini non indifferenti.

Problema #1: le performance non sono eccezionali, e anche su un iPad di quarta generazione non si riesce ad andare oltre agli 8-10 fotogrammi al secondo. Quando non c’è da fare lo scrolling questo non è un problema, ma non appena il numero di righe supera la dozzina allora passare da una riga all’altra diventa relativamente faticoso per l’utente medio.

Problema #2: per qualche motivo a me ignoto il comportamento degli oggetti Flash quando si visualizzano in un device dotato di display retina è poco comprensibile, per cui occorre realizzare due versioni di ogni oggetto, e quelle con compatibilità con i dispositivi retina devono essere pesantemente modificati e sono poco intuitivi da programmare, visualmente parlando.

Schermata 2014-03-11 alle 14.04.23

Per quanto concerne trackFinger, mi sono detto che questo era un buon compromesso da raggiungere, perché volevo prima di tutto fare uscire l’applicazione, e poi ho pensato che per l’utente medio non sarebbe stato un grandissimo problema.

Stiamo però realizzando anche una nuova versione di trackSlate, che dovrà non solo fare da ciak, ma anche, nelle nostre intenzioni, anche tenere un report completo di tutte le scene e le riprese, dunque, considerando il giorno medio su un set in cui si gira, mostrare decine se non centinaia di righe, ognuna dotata di molto testo e di diverse icone.

L’infrastruttura che avevo realizzato in Flash non sarebbe stata sufficiente. Di conseguenza mi sono messo all’opera per cercare di capire come poteva essere possibile realizzare una nuova versione del framework che consentisse di visualizzare tantissimo testo e di avere anche uno scrolling molto fluido.

Mi sono rimesso a lavorare su del codice che avevo iniziato a scrivere circa sei mesi fa quando stavo sviluppando l’applicazione per Italian Podcast Network.

IPNews sull'App Store
IPNews sull’App Store

Adesso questa app non si trova più nello store perché ho capito che il livello qualitativo non sarebbe mai stato all’altezza delle mie aspettative.

Ma torniamo al codice. L’idea era semplice e allo stesso tempo geniale: non mostrare tutte queste informazioni come se fossero del testo ma trasformare tutte le scritte in grafica e caricarle come texture all’interno di un mondo tridimensionale e lasciare che fosse il motore grafico OpenGL del device ad occuparsi della cosa. Mica cazzi.

OpenGL_ES_logo

Ve lo dico subito: quando avevo sviluppato questo codice sei mesi fa avevo sin dall’inizio visto che era decisamente veloce, qualcosa come 60 fotogrammi al secondo, ma la qualità delle scritte non era eccezionale. Non chiedetemi come mai, però la conversione da testo a grafica non era delle migliori., Dunque, ho lasciato perdere sono tornato al mio approccio con Flash.

Questa volta, però, mi sono intestardito e ho pensato di rifare tutto da zero e di riprovarci, avendo come obiettivo essenzialmente soltanto i device con display retina. Gli iPhone sono ormai, per il 90%, diffusi solo con dispositivi ad alta risoluzione, mentre per quanto concerne gli iPad, probabilmente siamo al 50% circa. Però, questa volta, dato che le linee da mostrare dovevano essere tantissime, mi sono detto che il compromesso che l’utente medio avrebbe accettato sarebbe stato quello di avere una visualizzazione veloce, anche se a scapito della qualità delle immagini.

User eXperience first.

E, allora, ho rifatto il mio motore di visualizzazione, chiamato “Viewport“.

viewport_logo (0-00-00-00)

Cercherò di descrivervelo senza fare troppi giri di parole. È fottutamente veloce.

Anzi, lo dico andando a capo:

È fottutamente veloce!

Ancora una volta sono andato incontro a due problemi:

Primo problema: su dispositivi non ho dotati di display retina la qualità del testo non è eccezionale (mentre su device ad alta risoluzione il testo è straordinariamente bello da vedersi).

Secondo problema: quando il numero di righe da visualizzare supera un certo numero, il tempo di preparazione della grafica risulta essere piuttosto elevato.

Se non vi dispiace inizierò a parlare di questo secondo problema e di come sono arrivato ad una soluzione.

Ho fatto un po’ di conti, e, mediamente, per una linea di testo, a seconda del device, viene richiesto circa 1/10-1/12 di secondo. In parole povere se devo preparare il display con 100 righe da visualizzare (e su un giorno su un set la cubatura questa) ci vogliono circa 8-10 secondi prima di poter accedere alla visualizzazione dei dati.

Ho cercato di fare un po’ di analisi, dato che attendere una schermata per circa 10 secondi non è assolutamente un’opzione, e ho capito che il collo di bottiglia è dato dalla trasformazione del testo in grafica.

txt > gfx (0-00-00-00)

Questo perché viene fatto a livello dell’applicazione e non del sistema operativo. Parliamoci chiaramente: se devo visualizzare la scritta “Ciao mondo!», devo prendere questa scritta, trasformarla in un’immagine e poi caricarla all’interno del mondo tridimensionale. Una scritta del genere è essenzialmente di dimensione di circa 200-250 pixel per 40-60 (a seconda del dispositivo su cui verrà letta). E, ovviamente non è che si possa essere troppo schizzinosi: se questa cosa va mostrata va anche convertita, prima o poi.

Come fare, allora, a mostrare qualcosa senza fare attendere così tanto l’utente?

Beh, ho scelto la strada più difficile ma nello stesso tempo più efficiente: mostrare all’utente qualcosa e, intanto che inizia ad usare le informazioni che sta guardando, aggiungere piano piano le righe, una ad una, fino a riempire la schermata.

vp_dgr01 (0-00-00-00)

Generalmente quando si mostrano delle informazioni, ce ne sono alcune che hanno più senso e altre che ne hanno meno. Come fare a decidere cosa ha più senso e dunque mostrare prima?

Nel caso di trackFinger e di trackSlate le informazioni da mostrare per prime sono le ultime generate. Ed è sempre così: del programma di posta elettronica, in Facebook, in Twitter, le cose che si trovano più in alto, dunque “all’inizio”, sono le ultime, quelle più nuove.

E così ho deciso di creare una sorta di coda: mostro all’utente le prime N righe, e poi se ce ne sono altre, queste vengono aggiunte una alla volta, alla ritmo di circa cinque al secondo visto che devo consentire anche l’interazione, intanto che l’utente può già lavorare su queste, eventualmente anche selezionandole. Il tempo di attesa per la schermata si accorcia, dunque, a circa un secondo.

In realtà ho ottimizzato anche il codice di conversione tra testi grafica, in modo da avere una banca di immagini già pronte, per cui se devo mostrare due volte la scritta “Ciao mondo!», non la devo trasformare due volte, ma mi riferisco all’immagine già pronta.

vp_dgr02 (0-00-00-00)

In più tutte le informazioni vengono comunque memorizzate all’interno del mondo tridimensionale, per cui la seconda volta che si accede a questa schermata non si dovrà fare altro che non inizializzarla dato che tutto quanto si troverà già pronto e trasformato.

Se si aggiunge una nuova riga, Il tempo di attesa sarà dunque di circa 1/5 di secondo, decisamente compatibile con i tempi di attesa degli utenti.

Non solo, dato che il mondo tridimensionale sarà comunque presente anche se non visualizzato, l’aggiunta di righe può essere effettuata anche in altre parti dell’applicazione, per cui non appena i dati sono pronti, anche se non devono essere visualizzati immediatamente, questi vengono comunque convertiti e la lista aggiornata prima ancora che l’utente lo richieda.

vp_dgr03 (0-00-00-00)

In questo momento la versione attuale del mio framework ha quasi tutte le caratteristiche che sono necessarie per diventare anche un prodotto commerciale, anche se non credo che lo venderò mai, mancano alcune possibilità, soprattutto quelle di aggiungere degli elementi in mezzo alla lista senza aggiungerli in coda. Ma si tratta di poca cosa, per cui nell’arco di qualche giorno tutto sarà pronto.

Insomma, it just works.

Torniamo adesso al primo problema, quello della qualità del testo. Ho fatto un po’ di ricerche, provando praticamente qualsiasi font di caratteri presente sui dispositivi iOS, e sono giunto ad un buon compromesso, quello che vedete in questa immagine è preso da un iPad 2:

IMG_0093

Cliccateci pure sopra così da vederla ingrandita.

Sono assolutamente convinto che questo non sia l’ottimo, ma è comunque un buonissimo risultato. E, sottolineo sempre, l’ottimo è nemico del buono. Inoltre, dato che i dispositivi non retina devono gestire, senza troppi giri di parole, sia metà della risoluzione orizzontale che metà di quella verticale, tutto si traduce in 1/4 dei pixel da muovere, per cui il tempo di conversione da testo a immagine è decisamente ridotto. E dunque anche compatibile con la potenza di calcolo di dispositivi relativamente datati.

Tanto per farvi capire, questo è viewPort con due (!) liste contemporaneamente a schermo:

All’inizio lo scrolling è lento perché viewPort sta comunque popolando le (due!) viewport (contemporaneamente). Una volta che il riempimento è terminato potete vedere quanto va veloce…

Insomma, questo è lo stato dell’arte. La versione 1.0 di viewPort non è così lontana e sarà sicuramente inclusa nella prossima release di trackFinger e in quelle successive di trackSlate.

Se siete arrivati fino a qui… Beh, vi devo una birra!

Annunci

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...