HTML Mobile App: 5 Consigli per aumentare le performance
Negli articoli precedenti (HTML5 Mobile App: transizioni ed animazioni CSS3 parte 1 e parte 2) abbiamo visto come poter realizzare applicazioni HTML5 e Javascript con interfacce che sfruttano animazioni CSS3, e come poter controllare quest’ultime grazie agli eventi che abbiamo a disposizione.
Oggi ti voglio mostrare alcune tecniche da affiancare a quelle già analizzate per migliorare l’esperienza utente e renderla più vicina, in termini di prestazioni e reattività, a quelle sviluppate nativamente.
1. Limita l’utilizzo di ombre e riempimenti gradienti e sfrutta l’accelerazione hardware
Se possibile evita di usare proprietà CSS “pesanti” come colori gradienti e ombre, le quali rallentano notevolmente il processo di rendering che la memoria centrale del dispositivo deve affrontare (fortunatamente il flat design ci è d’aiuto :)).
Smartphone e tablet presentano generalmente caratteristiche hardware molto meno potenti rispetto a quelle desktop, e risulta piuttosto facile provocare un memory “overload” causato dalla presenza di un numero troppo elevato di processi da gestire simultaneamente (il classico scenario in cui si verifica il crash dell’applicazione).
Una pratica molto diffusa ed efficace è quella di delegare parte dei processi di rendering alla GPU (la scheda grafica), favorendo la composizione dei livelli grafici, ovvero la trasformazione di gruppi di elementi DOM in immagini bitmap.
Si tratta di quella tecnica denominata hardware acceleration (o accelerazione hardware), che viene attivata tramite determinate proprietà CSS3.
Per approfondire il discorso dell’accelerazione hardware, sapere su quali proprietà agire ai fini delle prestazioni e capire come poter sfruttare la creazione dei livelli grafici, ti consiglio di leggere questo articolo
2. Semplifica la struttura DOM del documento
Una delle caratteristiche fondamentali di qualsiasi single page app (e quindi di ogni applicazione mobile sviluppata in HTML5) è la generazione del markup HTML lato-client, quindi tramite Javascript, utilizzando all’occorrenza dei sistemi di javascript templating.
Si tratta di un aspetto molto importante per contribuire alla velocità dell’interfaccia, dal momento che invece di generare codice HTML direttamente dal server, quest’ultimo è utilizzato soltanto per lo scambio dei dati.
Tuttavia bisogna fare attenzione a non abusare nella generazione del markup: un numero elevato di elementi DOM potrebbe scatenare troppi processi di rendering allo stesso tempo, portando ad un sovraccarico della memoria, ovvero lo stesso tipo di situazione che abbiamo visto nel punto uno.
Ecco alcune tecniche che possono contribuire ad alleggerire e rendere più semplice la struttura HTML della tua applicazione:
- Usa il minor numero possibile di elementi DOM
- Minimizza le modifiche e gli interventi sugli elementi DOM presenti nel documento: ognuna di esse potrebbe far ripetere il rendering per l’elemento interessato
- Rimuovi dal documento gli elementi non utilizzati al momento, e genera nuovi elementi quando hai bisogno di mostrarli all’utente
- Se necessario, modifica un elemento DOM prima di aggiungerlo al documento: ciò permette di richiamare il processo di rendering soltanto quando l’elemento viene inserito
Ecco un esempio che mette a confronto due porzioni di codice Javascript, che fanno essenzialmente la stessa cosa, ma con una ripercussione diversa sulle prestazioni:
3. Non utilizzare troppi framework esterni
Molte volte capita di includere nel progetto diversi tipi di framework solo per usufruire di una parte delle caratteristiche di ognuno (effetti CSS3, elementi UI, foglio di stile ecc), rallentando notevolmente i tempi di caricamento iniziale e quelli durante la creazione di nuovo markup.
È un errore comune aggiugere riferimenti che rimangono completamente inutilizzati o quasi,
Come parte di fogli di stile (o fogli di stile interi), file javascript o qualunque altro tipo di risorsa.
Prima di pubblicare il tuo progetto controlla sempre ciò che rimane inutilizzato, evita di includere interi framework e, se ne utilizzi soltanto una parte o se proprio hai bisogno di un determinato componente di quel framework, assicurati di personalizzarne il download: molte librerie permettono infatti di poter scegliere cosa includere sul pacchetto da scaricare, come nel caso di Twitter Bootstrap, Modernizr, jQuery UI, Animate.css e molti altri.
4. Usa lo scrolling nativo
Quando possibile cerca di applicare sempre lo scrolling nativo per mostrare i lunghi contenuti, incorporando il framework per lo scrolling javascript soltanto se il primo non è supportato.
Così facendo avrai due vantaggi principali:
- Eliminare il caricamento iniziale della libreria Javascript usata per lo scrolling quando non necessaria
- Usufruire delle prestazioni native del dispositivo, che sicuramente sono molto più performanti e fluide di quelle offerte da qualunque framework javascript
Ecco l’esempio di codice per abilitare lo scrolling nativo iOS su di un elemento con id #scrolling-wrapper, posizionato in modo assoluto nel documento:
#scrolling-wrapper{ position:absolute; top:48px; /*lasciamo lo spazio per l’header*/ bottom:0; left:0: right:0; /* visualizziamo lo scroll solo se il contenuto “fuoriesce” dal contenitore */ overflow: auto; /* attiviamo il touch nativo di iOS */ -webkit-overflow-scrolling: touch; } /*Di seguito un piccolo trucco per forzare la tecnica dell’accelerazione hardware (di cui abbiamo parlato nel punto 1), in modo da delegare alla GPU il rendering per tutti gli elementi che si trovano all’interno del contenitore */ #scrolling-wrapper > * { -webkit-transform: translateZ(0px); transform: translateZ(0px); }
5. Evita di andare troppo in profondità nella struttura del DOM ed usa la proprietà display:none invece che visibility:hidden
Evita di inserire troppi elementi DOM nidificati in modo da creare una struttura gerarchica troppo complessa: modificando infatti anche solo una proprietà CSS3 per l’elemento più interno è possibile riscatenare il processo di rendering per tutti gli elementi che lo contengono, risalendo fino al primo livello.
Credimi, ciò può avere un impatto negativo incredibile nelle performance della tua HTML5 Mobile App, rendendola lenta o provocandone addirittura il crash.
Nel punto 2 ti ho consigliato di eliminare gli elementi DOM che non vuoi visualizzare in un dato momento, per poi ricrearli quando ne hai bisogno; tuttavia ciò non è sempre possibile.
Molte volte capita che per qualche motivo non puoi rimuovere completamente un componente dell’interfaccia, ma allo stesso tempo abbiamo visto che lasciare nel documento troppi elementi può causare un sovraccarico della memoria centrale.
In questi casi resta soltanto una soluzione: nascondere l’elemento con la proprietà display:none, a discapito della proprietà visibility:hidden.
Il browser tratta gli elementi resi invisibili con la seconda proprietà come se fossero ancora visibili (rimangono cliccabili e mantengono un ingombro nel documento), pertanto “resta in ascolto” per eventuali modifche agli stili o alla posizione, ripetendo quindi il processo di rendering.
Un elemento nascosto invece dalla proprietà display viene completamente ignorato dal browser, che quindi non si preoccupa di fare attenzione ad eventuali modifiche CSS.
Conclusioni
Come avrai notato, focalizzarsi sulla riduzione del numero di volte in cui il processo di rendering viene ripetuto per ogni elemento DOM costituisce la base per la realizzazione di una Applicazione HTML Mobile (e non) fluida e reattiva.
Proprio per questo, se non lo stai già facendo, ti consiglio vivamente di testare continuamente le performance di ciò che stai sviluppando, utilizzando gli ottimi strumenti per lo sviluppatore messi a disposizione dai vari tipi di browser, che permettono di capire quale parte può essere migliorata e resa più “leggera”.
Se hai qualche consiglio o tecnica da aggiungere condividila lasciando un tuo commento!
10 commenti
Trackback e pingback
-
HTML Mobile App: 5 Consigli per aumentare le pe...
[…] Negli articoli precedenti (HTML5 Mobile App: transizioni ed animazioni CSS3 parte 1 e parte 2) abbiamo visto come poter… -
HTML Mobile App e Web App: il web ha bisogno delle VIEW | Your Inspiration Web
[…] abbiamo visto nel secondo punto di un precedente articolo, il processo di rendering di qualsiasi browser moderno, è condizionato…
Ciao Giacomo,
consigli utili, anche se non mi trovi per nulla d’accordo sul punto 2.
JavaScript e’ un linguaggio client-side il che vuol dire che viene processato dal client, e come sappiamo, le risorse messe a disposizione di JavaScript sono abbastanza limitate.
Il fatto di generare l’html server-side non incide minimamente sulla velocita’ di caricamento della pagina.
Forse mi sono perso io qualcosa, ma non credo che generare HTML in JavaScript sia piu’ veloce che averlo gia’ a disposizione al momento dell’apertura della pagina…
Per il resto, buoni suggerimenti :)
Ciao Nicolas, grazie per il commento.
Quello che dici è vero, il server è più “potente” del client, soprattutto di quelli mobile.
Tuttavia nel punto 2 stavo cercando di esporre il fatto di limitare la quantità di dati scambiati tra server e client, in modo da diminuire i tempi di attesa. I dispositivi mobile, proprio perché “mobili”, non sempre godono di una veloce connessione, pertanto cercare di limitare la quantità di dati ottenuti dal server è uno dei fattori che maggiormente incide sulla user-experience di qualsiasi applicazione, anche di quelle native.
Sulla base di ciò, generare codice HTML lato-server per poi “scaricarlo” dall’app ed utilizzarlo come parte dell’interfaccia, è uno degli approcci più errati che si possa compiere in termini di velocità e prestazioni.
Tra l’altro, agire in questa maniera significherebbe decentralizzare parte dell’applicazione in una risorsa ad essa esterna, perdendo anche in fatto di mantenibilità del codice.
Tra l’altro gli ottimi sistemi di Javascript templating sono costantemente ottimizzati e migliorati per avere il massimo delle prestazioni nella generazione del markup lato-client, e pertanto non incidono negativamente (sempre se usati in modo corretto) sulla velocità di una applicazione CSS3 e javascript.
Ciao Giacomo, grazie a te per aver risposto.
“Sulla base di ciò, generare codice HTML lato-server per poi “scaricarlo” dall’app ed utilizzarlo come parte dell’interfaccia, è uno degli approcci più errati che si possa compiere in termini di velocità e prestazioni.”
Ma quindi stiamo parlando di un’app nativa? Altrimenti non riesco proprio a dare un senso alla frase “scaricare HTML da un server.”.
Ciao Nicolas, vedo che stai facendo un po di confusione.
Ti spiego meglio: in un app non nativa (realizzata quindi in HTML5, CSS3 e Javascript, ovvero quello di cui stiamo parlando) è buona cosa “preparare” il markup su file locali da richiamare al momento del bisogno, o direttamente all’interno di un file js incluso nel documento. Quando l’applicazione ottiene dei dati dinamici (o dal server o dall’utente che sta usando l’applicazione, magari attraverso un form o un quiz o qualunque altro tipo di interazione) che devono essere visualizzati, essi vengono integrati al markup precedentemente “preparato” per generare l’HTML da “stampare a video”.
L’errore che molti compiono è quello di non “preparare” il proprio markup all’interno dei file (.html o .js) dell’applicazione, ma di recuperarlo dal server assieme ai dati dinamici ogni volta che questi devono essere mostrati all’utente, anzichè “richiedere” al server solo i dati senza markup.
Ciò si traduce in una quantità di dati maggiori richiesti al server.
Ecco un esempio di dati ricevuti dal server in modo “veloce”;
[
{nome: “Mario”, Cognome: “Rossi”, Data: “18 Marzo 1988” },
{nome: “Pinco”, Cognome: “Pallino”, Data: “22 Aprile 1979” }
{nome: “Franco”, Cognome: “Franchi”, Data: “28 Agosto 1965” }
]
Mentre invece ecco un possibile esempio di dati ricevuti dal server in modo “lento”, che dipende dalla quantità di tag inseriti;
Non credi che la chiamata al server sia un po più lenta nel secondo caso? :)
Ora direi che e’ piu’ chiaro cio’ che volevi dire, ma permettimi di dire che dall’articolo io non sono riuscito a capire bene di cosa parlavi.
Sicuramente una risposta contenente un JSON array, o qualunque tipo di risposta JSON e’ piu’ veloce di una risposta contentente anche HTML. Ci sono comunque tantissimi altri aspetti da prendere in considerazione per questo punto…
Certo :)
Anzi mi scuso se non sono stato chiaro e ti ringrazio per i commenti, magari abbiamo potuto spiegare meglio la cosa a coloro che non avevano capito cosa intendessi. La prossima volta cercherò di essere più chiaro.
Ovvio, gli aspetti sono molti, ma affrontarli tutti in un articolo non è possibile..
Cioa voelvo porti un paio di domande,
1 come vedi Angular per la gestione dei tamplate in html
2 Effettivamente non ho capito ancora bene la best practise per mobile
Parere tuo è meglio
1 Gestire la parte dei dati (nel mio caso con java) percui pagina jsp
o
2 gestire un hml e far chiamate json che mi popolano html?
MI chiedevo ma essendo lato server i dati non vengono già elaborati dal server percui gia presenti , senza far nessuna chiamata lato client ??
grazie
sirio
Ciao Sirio,
grazie per il commento.
1. per quanto riguarda i template di angularJS non sono affatto male, anche se solitamente mi piacciono di più i sistemi di templating che offrono maggiori possibilità di personalizzazione e libertà d’azione (come Handlebars, underscore.js ecc.). Tuttavia, se usi angularJS per le tue single page app, allora è buona norma cercare di utilizzare comunque il suo sistema di templating integrato.
2. per quanto riguarda la parte dei dati non ho ben capito cosa tu intenda, ma sicuramente è buona pratica non passare markup HTML da client a server o viceversa. In altre parole non richiedere in remoto codice HTML ma solo i dati puri.
Per avere un idea consulta il mio secondo commento in risposta a Nicolas, che più o meno ha fatto la stessa domanda.
Giacomo