Introduzione
Gran parte di HTML5 mira a fornire il supporto del browser nativo per i componenti e le tecniche che abbiamo ottenuto finora tramite le librerie JavaScript. L'utilizzo di queste funzionalità, se presenti, può offrire un'esperienza molto più rapida ai tuoi utenti. In questo tutorial non riassumerò l'eccellente ricerca sul rendimento che hai visto sul sito Rendimento eccezionale di Yahoo o nei documenti di PageSpeed e sul sito Facciamo il web più veloce di Google. Mi concentrerò invece su come l'utilizzo di HTML5 e CSS3 oggi può rendere le tue app web più responsive.
Suggerimento 1: utilizza lo spazio di archiviazione web al posto dei cookie
Sebbene i cookie siano utilizzati da anni per monitorare i dati utente unici, presentano gravi svantaggi. Il più grande difetto è che tutti i dati dei cookie vengono aggiunti a ogni intestazione di richiesta HTTP. Ciò può avere un impatto misurabile sui tempi di risposta, in particolare durante le richieste XHR. Pertanto, una best practice è ridurre le dimensioni dei cookie. In HTML5 possiamo fare di meglio: utilizzare sessionStorage e localStorage al posto dei cookie.
Questi due oggetti di archiviazione web possono essere utilizzati per mantenere i dati utente lato client per la durata della sessione o a tempo indeterminato. Inoltre, i loro dati non vengono trasferiti al server tramite ogni richiesta HTTP. Hanno un'API che ti farà felice di sbarazzarti dei cookie. Ecco entrambe le API, che utilizzano i cookie come opzione di riserva.
// if localStorage is present, use that
if (('localStorage' in window) && window.localStorage !== null) {
// easy object property API
localStorage.wishlist = '["Unicorn","Narwhal","Deathbear"]';
} else {
// without sessionStorage we'll have to use a far-future cookie
// with document.cookie's awkward API :(
var date = new Date();
date.setTime(date.getTime()+(365*24*60*60*1000));
var expires = date.toGMTString();
var cookiestr = 'wishlist=["Unicorn","Narwhal","Deathbear"];'+
' expires='+expires+'; path=/';
document.cookie = cookiestr;
}
Suggerimento 2: utilizza le transizioni CSS anziché l'animazione JavaScript
Le transizioni CSS ti consentono di creare una transizione visiva accattivante tra due stati. La maggior parte delle proprietà di stile può essere transizionata, ad esempio modificando l'ombra del testo, la posizione, lo sfondo o il colore. Puoi utilizzare le transizioni in stati di pseudo-selettori come :hover o da moduli HTML5, :invalid e :valid (esempio con stati di convalida del modulo). Tuttavia, sono molto più potenti e possono essere attivati quando aggiungi qualsiasi classe a un elemento.
div.box {
left: 40px;
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
div.box.totheleft { left: 0px; }
div.box.totheright { left: 80px; }
Aggiungendo le classi di attivazione/disattivazione totheleft e totheright puoi spostare la casella. Confronta questa quantità di codice con quella di una raccolta di animazioni JavaScript. È chiaro che il numero di byte inviati al browser è molto inferiore quando si utilizza un'animazione basata su CSS. Inoltre, con l'accelerazione a livello di GPU, queste transizioni visive saranno il più fluide possibile.
Suggerimento 3: utilizza i database lato client anziché i roundtrip del server
Database SQL web e IndexedDB introducono i database lato client. Anziché utilizzare il pattern comune di invio dei dati al server tramite XMLHttpRequest o invio di moduli, puoi sfruttare questi database lato client. La riduzione delle richieste HTTP è un obiettivo principale di tutti gli addetti al rendimento, quindi l'utilizzo di questi come archivio dati può far risparmiare molti viaggi tramite XHR o post del modulo al server. localStorage e sessionStorage potrebbero essere utilizzati in alcuni casi, ad esempio per acquisire l'avanzamento dell'invio dei moduli, e sono notevolmente più veloci delle API di database lato client.
Ad esempio, se hai un componente di griglia di dati o una posta in arrivo con centinaia di messaggi, memorizzando i dati localmente in un database eviterai i roundtrip HTTP quando l'utente vuole eseguire ricerche, filtrare o ordinare. Un elenco di amici o un completamento automatico dell'input di testo potrebbe essere filtrato su ogni pressione di tasto, per un'esperienza utente molto più reattiva.
Suggerimento 4: i miglioramenti a JavaScript offrono vantaggi considerevoli in termini di prestazioni
In JavaScript 1.6 sono stati aggiunti molti metodi aggiuntivi al prototipo Array. Ora sono disponibili nella maggior parte dei browser, ad eccezione di IE. Ad esempio:
// Give me a new array of all values multiplied by 10.
[5, 6, 7, 8, 900].map(function(value) { return value * 10; });
// [50, 60, 70, 80, 9000]
// Create links to specs and drop them into #links.
['html5', 'css3', 'webgl'].forEach(function(value) {
var linksList = document.querySelector('#links');
var newLink = value.link('http://google.com/search?btnI=1&q=' + value + ' spec');
linksList.innerHTML += newLink;
});
// Return a new array of all mathematical constants under 2.
[3.14, 2.718, 1.618].filter(function(number) {
return number < 2;
});
// [1.618]
// You can also use these extras on other collections like nodeLists.
[].forEach.call(document.querySelectorAll('section[data-bucket]'), function(elem, i) {
localStorage['bucket' + i] = elem.getAttribute('data-bucket');
});
Nella maggior parte dei casi, l'utilizzo di questi metodi nativi consente velocità notevolmente superiori rispetto al tipico ciclo for, ad esempio: for (var i = 0, len = arr.length; i < len; i++).
L'analisi JSON nativa (tramite JSON.parse()) sostituisce il file json2.js che siamo abituati a includere da un po' di tempo. JSON nativo è molto più veloce e sicuro rispetto all'utilizzo di uno script esterno ed è già disponibile in IE8, Opera 10.50, Firefox 3.5, Safari 4.0.3 e Chrome.
String.trim nativo è un altro buon esempio di codice non solo più veloce degli equivalenti JS lunghi, ma anche potenzialmente più corretto. Tecnicamente, nessuna di queste aggiunte di JavaScript è HTML5, ma rientrano nell'ambito delle tecnologie che sono diventate disponibili di recente.
Suggerimento 5: utilizza il file manifest della cache per i siti live, non solo per le app offline
Due anni fa, WordPress utilizzava Google Gears per aggiungere una funzionalità chiamata WordPress Turbo. In sostanza, ha memorizzato nella cache localmente molte delle risorse utilizzate nel pannello di amministrazione, velocizzando l'accesso ai file. Possiamo replicare questo comportamento con l'attributo applicationCache di HTML5 e cache.manifest.
La cache dell'app ha un leggero vantaggio rispetto all'impostazione delle intestazioni Expires; poiché crei un file dichiarativo che indica le risorse statiche che possono essere memorizzate nella cache, i browser possono ottimizzarle notevolmente, magari anche memorizzandole in cache prima dell'utilizzo.
Considera la struttura di base del tuo sito come un modello. Hai dati che potrebbero cambiare, ma il codice HTML che li circonda in genere rimane abbastanza coerente. Con la cache dell'app puoi trattare l'HTML come una serie di modelli puri, memorizzare nella cache il markup tramite cache.manifest e poi inviare JSON tramite rete per aggiornare i contenuti. Questo modello è molto simile a quello di un'app di notizie nativa per iPhone o Android.
Suggerimento 6: attiva l'accelerazione hardware per migliorare l'esperienza visiva
Nei browser più diffusi, molte operazioni visive possono sfruttare l'accelerazione a livello di GPU, il che può rendere molto più fluide le operazioni visive altamente dinamiche. L'accelerazione hardware è stata annunciata per Firefox Minefield e IE9 e Safari ha aggiunto l'accelerazione a livello hardware nella versione 5. (È arrivata in Safari mobile molto prima). Chromium ha appena aggiunto le trasformazioni 3D e l'accelerazione hardware per Windows. Le altre due piattaforme saranno disponibili a breve.
L'accelerazione della GPU viene attivata solo in un insieme di condizioni abbastanza limitato, ma le trasformazioni 3D e l'opacità animata sono i modi più comuni per attivare l'opzione. Un modo un po' hacker, ma non invadente, per attivarlo è:
.hwaccel { -webkit-transform: translateZ(0); }
Tuttavia, non ci sono garanzie. :) Con l'accelerazione hardware supportata e attivata, la traduzione, la rotazione, la scalatura e l'opacità animate saranno decisamente più fluide con il compositing GPU. Avranno il vantaggio di essere gestiti direttamente sulla GPU e non richiedono il ricalcolo dei contenuti del livello. Tuttavia, qualsiasi proprietà che influisce sul layout della pagina sarà comunque relativamente lenta.
Suggerimento 7: per le operazioni che richiedono un'elevata potenza di calcolo della CPU, i web worker sono la soluzione ideale
I web worker hanno due vantaggi significativi: 1) sono veloci. 2) Mentre eseguono le tue attività, il browser rimane reattivo. Dai un'occhiata alla presentazione in HTML5 per i lavoratori in azione. Ecco alcune possibili situazioni in cui potresti utilizzare i worker web:
- Formattazione del testo di un documento lungo
- Evidenziazione della sintassi
- Elaborazione immagini
- Sintesi delle immagini
- Elaborazione di array di grandi dimensioni
Suggerimento 8: attributi e tipi di input dei moduli HTML5
HTML5 introduce un nuovo insieme di tipi di input, eseguendo l'upgrade del nostro insieme di text, password e file in modo da includere search, tel, url, email, datetime, date, month, week, time, datetime-local, number, range e color. Il supporto dei browser per questi elementi varia, ma al momento Opera ne implementa la maggior parte. Con il rilevamento delle funzionalità puoi determinare se il browser ha il supporto nativo (e offrirà un'interfaccia utente come un selettore della data o un selettore di colori) e, in caso contrario, puoi continuare a utilizzare i widget JS per svolgere queste attività comuni.
Oltre ai tipi, ai normali campi di immissione sono state aggiunte alcune funzionalità utili. L'input placeholder offre un testo predefinito che viene cancellato quando fai clic al suo interno e autofocus consente di mettere a fuoco il cursore al caricamento della pagina, in modo da poter interagire immediatamente con il campo. La convalida dell'input è un'altra funzionalità in arrivo con HTML5. L'aggiunta dell'attributo required significa che il browser non consentirà l'invio del modulo finché il campo non sarà compilato. Inoltre, l'attributo pattern ti consente di specificare un'espressione regolare personalizzata per l'input da verificare. I valori non validi bloccano l'invio del modulo. Questa sintassi dichiarativa rappresenta un grande upgrade non solo per la leggibilità del codice sorgente, ma anche per una significativa riduzione del codice JavaScript necessario. Anche in questo caso, puoi utilizzare il rilevamento delle funzionalità per offrire una soluzione di riserva se non è presente il supporto nativo per queste funzionalità.
Se utilizzi i widget nativi, non devi inviare il codice JavaScript e CSS necessario per visualizzarli, il che consente di velocizzare il caricamento della pagina e, probabilmente, di migliorare la reattività dei widget. Per provare alcuni di questi miglioramenti all'input, consulta la presentazione HTML5.
Suggerimento 9: utilizza gli effetti CSS3 anziché richiedere sprite di immagini di grandi dimensioni
CSS3 offre molte nuove possibilità di stile che sostituiscono l'uso delle immagini per rappresentare con precisione il design visivo. Sostituire un'immagine 2K con 100 byte di CSS è un enorme vantaggio, senza contare che hai rimosso un'altra richiesta HTTP. Ecco alcune proprietà da conoscere:
- Sfumature lineari e radiali
- Border-radius per gli angoli arrotondati
- Box-shadow per ombreggiature e bagliore
- RGBA per l'opacità alfa
- Trasformazioni per la rotazione
- Maschere CSS
Ad esempio, puoi creare pulsanti molto eleganti tramite gradienti e riprodurre molti altri effetti senza immagini. Il supporto dei browser per la maggior parte di queste funzionalità è molto solido e puoi utilizzare una libreria come Modernizr per rilevare i browser che non supportano le funzionalità al fine di utilizzare le immagini in caso di piano di riserva.
Suggerimento 10: WebSocket per una pubblicazione più rapida con una larghezza di banda inferiore rispetto a XHR
WebSockets è stato progettato in risposta alla crescente popolarità di Comet. Ora esistono vantaggi nell'utilizzo di WebSockets, invece del modello Comet over XHR.
WebSockets ha un framing molto leggero, quindi la larghezza di banda che consuma è spesso inferiore a quella di XHR. Alcuni report indicano una riduzione del 35% nei byte inviati tramite cavo. Inoltre, con volumi più elevati, la differenza di rendimento in termini di invio di messaggi è più evidente. In questo test, è stato registrato che XHR ha un tempo aggregato superiore del 3500% rispetto a WebSockets. Infine, Ericcson Labs ha preso in considerazione le prestazioni di WebSocket e ha riscontrato che i tempi di ping su HTTP erano 3-5 volte superiori rispetto a WebSocket a causa di requisiti di elaborazione più sostanziali. Hanno concluso che il protocollo WebSocket era chiaramente più adatto per le applicazioni in tempo reale.
Risorse aggiuntive
Per consigli su misurazione e rendimento, ti consigliamo di utilizzare le estensioni di Firefox Page Speed e YSlow. Inoltre, Speed Tracer per Chrome e DynaTrace Ajax per IE forniscono un livello più dettagliato di registrazione dell'analisi.