No. 202

Buongiorno! Al “castello Lanyrd” abbiamo appena lanciato la versione mobile del nostro sito, che memorizza i dati degli eventi a cui assistete per vederli offline. Ho ridotto i bit offline a una semplice demo e ho pubblicato tutto il codice su Github. Ma prima di immergerci nel codice, lasciate che vi racconti una storia vera, assolutamente vera.

Mi trovavo ad un party, uno di quelli in cui gli ospiti si conoscono a malapena. Facevo parte di un piccolo gruppo che stava cercando, non senza disagi, di fare le presentazioni. Una donna piuttosto bella si rivolse ad uno dei membri più timidi del gruppo, presentandosi come “Dev” e chiese: “E tu che lavoro fai?”

“Oh, sono il LocalStorage.”, rispose, chiaramente a disagio. “Fornisco un'interfaccia di scripting per memorizzare del testo che viene mantenuto tra le pagine e le sessioni del browser.”

“Sì, praticamente è uno scaffale!”, interruppe un altro. Il gruppo ridacchiò alle spalle di LocalStorage. Io rimasi in silenzio, perché conoscevo abbastanza bene quel ragazzo.

Un altro membro del gruppo si fece avanti. “Ciao, sono ApplicationCache” disse, spostandosi per stringere la mano di Dev, “Faccio diventare la tua esperienza offline da pessima a fantastica: solo un file in più e voilà! Funziona. Nessuna preoccupazione, nessun bisogno di fare ‘scripting𔃷”. Sì, fece le virgolette con le dita mentre diceva ‘scripting’. A quel punto stavo stringendo i denti, perché sapevo che aveva ingrandito enormemente le sue capacità senza che gli altri lo vedessero. Tuttavia, se avessi gridato “cavolate” io avrei fatto la figura dell'idiota.

Mi sono sentito male per non fatto nulla in quella serata completamente reale. È doloroso vedere articoli che lodano la facilità d'uso di ApplicationCache, scritti da persone che l'hanno chiaramente visto superficialmente. Devo mettere subito le cose in chiaro: sono qui per dirvi che ApplicationCache è una cretinata.

Ora, non intendo dire che sia completamente inutile o che dovrebbe essere evitato, dovete solo essere molto cauti quando ci lavorate e nel modo in cui lo usate. Se lo usate nel modo sbagliato, la stupidità si diffonde tutto intorno, fino all'utente finale. Leggendo le mie esperienze traumatiche con AppCache, saprete cosa aspettarvi da AppCache e come gestirlo.

Quando è utile l'accesso offline?

Siamo meglio connessi di quanto non lo siamo mai stati, ma non siamo sempre connessi. Ad esempio, sto scrivendo questo articolo su un treno che sfreccia attraverso le pianure povere di dati del West Sussex. In alternativa, potreste scegliere di essere offline. Quando uso la connessione dati all'estero mi pare di sentire i tappi di champagne che saltano negli uffici del mio network provider. So di avere un'emorragia di soldi quando uso il roaming dati, ma internet ha dei dati di cui ho bisogno e non mi fa accedere alla maggior parte di questi senza una connessione funzionante.

I siti utili offline si suddividono generalmente in due categorie: quelli che ti permettono di fare cose e quelli che ti permettono di cercare cose.

I siti che permettono di “cercare cose” includono Wikipedia, YouTube e Twitter. Il grosso del carico tende ad essere sul server e c'è una gran quantità di dati a disposizione degli utenti, che però ne usano solo una parte.

I siti che permettono di “Fare cose” includono Cut the Rope, CSS Lint e Google Docs. Per questa tipologia di siti, il grosso del carico è a lato client. Offrono una quantità limitata di dati, ma potete usare quei dati in molti modi o creare i vostri dati. Questo è il caso per cui è stato realizzato Application Cache, quindi cominceremo da qui per una semplice introduzione.

Mettere offline un sito per “fare cose”

Sprite Cow ricade nella categoria “fare cose”. Le CSS sprites sono ottime per le prestazioni, ma trovare la dimensione e la posizione di un oggetto in una sprite è piuttosto macchinoso. Sprite Cow carica lo sprite sheet e ritorna il CSS per mostrarne una particolare porzione. È un file html, alcuni elementi e tutto il processing viene fatto a lato client: il server non fa nulla se non mandare i files.

Sarebbe bello poter usare Sprite Cow in treno, così come facciamo con le app native. Per fare ciò, creiamo un manifest file che elenchi tutte gli elementi di cui ha bisogno il sito:


CACHE MANIFEST

assets/6/script/mainmin.js
assets/6/style/mainmin.css
assets/6/style/fonts/pro.ttf
assets/6/style/imgs/sprites1.png

... Poi colleghiamo quel manifest alla pagina html mediante un attributo:

<html manifest="offline.appcache">

La pagina HTML stessa non è elencata nel manifest. Le pagine che si associano ad un manifest ne diventano parte.

In pratica, se visitate Sprite Cow con una connessione dati, sarete in grado di visitarlo in seguito senza una connessione.

Il tab “resource” nel Web Inspector di Chrome vi mostrerà i files caricati dal manifest e quali pagine vi puntano. Se avete bisogno di svuotare quelle cache, andate su chrome://appcache-internals/.

Sulle prime, questo può sembrare una soluzione magica al problema. Sfortunatamente, stavo mentendo quando ho detto che questa sarebbe stata una semplice introduzione. La specifica di ApplicationCache è come una cipolla: ha molti strati e man mano che li togliete, cominciate a lacrimare.

Problema n.1: i files provengono sempre da ApplicationCache, anche se siete online.

Quando visitate Sprite Cow, ottenete subito la versione che avete in cache. Una volta che la pagina ha finito di essere caricata, il browser cercherà degli aggiornamenti al manifest e ai file in cache.

Tutto ciò suona come un modo bizzarro per fare cose ma vuol dire che il browser non deve attendere che la connessione scada prima di decidere che siete offline.

ApplicationCache attiva un evento updateready per farci sapere che c'è del contenuto aggiornato, ma non possiamo semplicemente fare il refresh della pagina a questo punto, perché l'utente potrebbe aver già interagito con la versione che ha già.

Non si tratta di un grosso problema, dal momento che la versione vecchia probabilmente è sufficientemente buona. Se dovesse essere necessario, possiamo mostrare un piccolo messaggio “È disponibile un aggiornamento. Fai refresh per aggiornare”. Potreste averlo visto in alcune app di Google come Reader e Gmail.

Oh, vi ricordate quattro paragrafi fa quando dissi che ApplicationCache cerca il contenuto aggiornato dopo aver caricato la pagina? Mentivo.

Problema n.2: ApplicationCache si aggiorna solo se il contenuto stesso del manifest è cambiato.

HTTP ha già un modello di caching. Ogni file può definire come dovrebbe essere messo in cache. Anche ad un livello base, i file singoli possono dire “Non mettermi mai in cache” oppure “controlla con il server, ti dirò se c'è un aggiornamento” oppure “assumi che io vada bene fino al 1 Aprile 2022”.

Tuttavia, immaginatevi di avere 50 pagine html nel vostro manifest. Ogni volta che ne visitate una di queste online, il browser dovrebbe fare 50 http request per vedere se avete bisogno di un update.

Come workaround leggermente insolito, il browser cercherà gli aggiornamenti solo dei file elencati nel manifest se il file del manifest stesso è cambiato dall'ultima volta che il browser ha controllato. Va bene qualsiasi cambiamento che renda diverso il manifest anche di un solo byte.

Questo funziona in maniera piuttosto trasparente per gli elementi statici che vengono idealmente caricati attraverso un content delivery network e che non cambiano mai. Quando il CSS/JavaScript/etc. cambiano, viene caricato sotto ad un differente url, il che vuol dire che il contenuto del manifest cambia. Se non avete familiarità con “far-future caching” e le CDN, leggete la guida con le best practices per le performance di Yahoo!.

Alcune risorse semplicemente non possono cambiare il proprio url in questo modo, come ad esempio le nostre pagine HTML. ApplicationCache non cercherà aggiornamenti a questi files senza un piccolo incoraggiamento. Il modo più semplice per farlo consiste nell'aggiungere un commento al proprio manifest e cambiarlo quando serve.


CACHE MANIFEST
# v1

whatever.html

I commenti nel manifest cominciano con un #. Se aggiorno whatever.html dovrei cambiare il mio commento a # v2, facendo così scattare un aggiornamento. Potrei automatizzarlo con un build script che mi mandi fuori qualcosa di simile a ETAG come un commento per ciascun file nel manifest, così che ciascun cambiamento nel file è certo che cambierà il contenuto del manifest.

Comunque, aggiornare il testo nel manifesto non garantisce che le risorse all'interno saranno aggiornate dal server.

Problema #3: ApplicationCache è una cache aggiuntiva, non alternativa.

Quando il browser aggiorna ApplicationCache, richiede gli url come farebbe di solito. Obbedisce alle normali istruzioni di caching: se un header di un oggetto dice “assumi che io sia valido fino al 1 Aprile 2022” il browser supporrà che la risorsa sia davvero valida fino al 1 Aprile 2022 e non darà fastidio al server per un aggiornamento.

Questa è una buona cosa perché potete usarla per tagliare il numero di richieste che il browser deve fare quando cambia il manifest.

Tutto ciò può cogliere le persone di sorpresa mentre stanno facendo esperimenti volti a capire se i propri server non mandino gli header della cache. Senza specifiche, il browser tirerà ad indovinare sulla cache. Potete aggiornare whatever.html e il manifest, ma il browser non aggiornerà il file perché “supporrà” che non abbia bisogno di aggiornamenti.

Tutti i file che inviate dovrebbero avere degli header della cache è questo risulta specialmente importante per tutto quello che c'è nel vostro manifest e per il manifest stesso. Se è molto probabile che un file venga aggiornato, dovrebbe essere inviato con no-cache. Se il file cambia poco frequentemente, è meglio optare per must-revalidate. Ad esempio, must-revalidate è una buona scelta per il file manifest stesso. Oh, già che stiamo parlando di questo...

Problema n.4: mai mai fare “far-future cache” nel manifest.

Potreste pensare di poter trattare il vostro manifest come un file statico, come in “assumi che io sia valido fino al 1 Aprile 2022” poi cambiare l'url al manifest quando dovete fare un aggiornamento.

No! Non fatelo! *sberla*

Ricordatevi il Problema n.1: quando l'utente visita una pagina una seconda volta, otterrà la versione di ApplicationCache. Se avete cambiato l'url al manifest, sfortuna, la versione memorizzata dall'utente punta ancora al vecchio manifest, che ovviamente è identico byte per byte, quindi non si aggiorna alcunché. Mai.

Problema n.5: le risorse non in cache non verranno caricate in una pagina in cache.

Se mettete in cache index.html ma non cat.jpg, quell'immagine non verrà mostrata su index.html anche se siete online. No, davvero, quello è il comportamento atteso, controllate voi stessi.

Per disabilitare questo comportamento, usate la sezione NETWORK del manifest.


CACHE MANIFEST
# v1

index.html

NETWORK:
*

L'* indica che il browser dovrebbe permettere tutte le connessioni alle risorse non memorizzate da una pagina in cache. Potete qui vederlo applicato all'esempio precedente. Ovviamente queste connessioni falliranno mentre siete offline.

Ben fatto: siete arrivati alla fine dell'esempio di ApplicationCache. Sì, davvero, abbiamo visto il caso semplice. Mi spiace. Cerchiamo qualcosa di più difficile.

Mettere offline un sito che “fa cercare cose”

Come ho detto all'inizio di questo articolo (ricordate quant'ero felice?), Lanyrd ha recentemente lanciato un sito mobile che permette alla gente di guardare i programmi, i luoghi, chi partecipa alle conferenze e altro ancora. L'accesso offline a questi dati è importante mentre si è in viaggio e si devono affrontare dei costi di roaming.

C'è troppo contenuto per poter mettere tutto offline, ma a ciascun utente di solito interessano solo gli eventi a cui partecipa.

Il vecchio Dive into HTML5 ci mostra un esempio in cui si mette offline, un altro sito che permette di cercare cose. Funziona usando un manifest quasi vuoto a cui sono collegate tutte le pagine, così man mano che gli utenti navigano nel sito, quelle pagine diventano implicitamente parte della loro cache. Quando saranno offline, saranno in grado di visitare ciascuna delle pagine che hanno precedentemente visitato.

Questa soluzione è incredibilmente semplice, ma grazie ad alcuni “goffi pezzi” della specifica, si rivela essere un completo disastro. Tanto per cominciare, all'utente non viene data nessuna indicazione di quale sia il contenuto disponibile mentre si è offline e non c'è una API JavaScript che possiamo usare per arrivare a tale informazione. Potremmo scaricare e analizzare il manifest con JavaScript, ma tutte queste pagine Wikipedia sono memorizzate in cache implicitamente e pertanto non sono elencate.

Inoltre, ricordatevi del Problema n.1: viene visualizzata la versione in cache piuttosto che la versione proveniente dal server. La pagina viene congelata per l'utente quando questo la guarda per la prima volta, ma come abbiamo visto nel Problema n.2 possiamo fare in modo che il browser cerchi degli aggiornamenti cambiando il testo nel file manifest. Tuttavia, quando cambiamo il file manifest? Ogni volta che viene aggiornata una voce di Wikipedia? In questo modo, gli aggiornamenti sarebbero troppo frequenti, infatti se un manifest cambia tra l'inizio e la fine di un aggiornamento, il browser considererà fallito questo aggiornamento (step 24).

La frequenza di questi aggiornamenti è un problema, ma il vero killer è il peso di questi aggiornamenti. Prendete ad esempio il numero di pagine di Wikipedia che avete visitato: un centinaio? Migliaia? Un aggiornamento AppCache implica lo scaricamento di ogni singola pagina. AppCache non ci dà un modo per rimuovere implicitamente gli oggetti memorizzati, così quel numero continuerà a crescere e crescere finché non raggiungerà un qualche tipo di limite della cache del browser ed il mondo esploderà. Non va bene.

Cosa vogliamo da un sito di riferimento che possiamo mettere offline?

I requisiti che vorrei per un sito di riferimento con capacità offline sono le seguenti:

  • deve mostrare dati aggiornati mentre sono collegato, come farebbe se non ci fosse ApplicationCache,
  • deve permettere a noi sviluppatori di controllare quale contenuto è presente nella cache, quando viene messo in cache e in che modo,
  • permetterci di rinviare alcune parti di quel controllo all'utente, magari sotto forma di un pulsante “Save offline” o “Read later”
  • fare in modo che una sola visita una qualsiasi pagina dia al browser ciò di cui ha bisogno per mostrare il contenuto offline.

ApplicationCache, per quanto si vanti, non rende semplice tutto ciò. Se una pagina ha un manifest, viene messa in cache. Non c'è modo che la pagina racconti al browser delle sue capacità offline senza che finisca in cache essa stessa.

Limitare la portata di ApplicationCache

Il modo più semplice per far sì che una pagina si comporti come se non ci fosse ApplicationCache è quello di dare la pagina senza un manifest. Possiamo dire al browser che ci sono cose offline immettendo un iframe nascosto che punti ad una pagina che abbia effettivamente un manifest.

Visitate questa pagina mentre siete online. Una volta che l'avete fatto, sarete in grado di visitare questa pagina mentre siete offline. La prima pagina non è in cache, quindi l'utente avrà sempre le informazioni più aggiornate da quella.

Tuttavia questa cosa non è molto impressionante. Se visitate la prima pagina quando siete offline, non otterrete nulla.

Fallback

Il manifest di ApplicationCache ci permette di specificare una risorsa di fallback da usare quando una certa richiesta fallisce.


CACHE MANIFEST

FALLBACK:
/ fallback.html
/assets/imgs/avatars/ assets/imgs/avatars/default-v1.png

Questo dice ad ApplicationCache di mostrare fallback.html ogni volta che una richiesta fallisce, a meno che la richiesta fallisca all'interno di /assets/imgs/avatars/, nel qual caso verrà usata un'immagine di fallback.

Per vedere come funziona in pratica, visitate questa pagina. Andateci di nuovo senza una connessione di rete e al suo posto vi verrà mostrata una pagina di fallback. Vedete che non è un “hard redirect”? Rimane l'url della pagina originale e questo ci sarà utile.

Incidentalmente, il fatto di avere un fallback fa rilassare le regole di blocco della rete che abbiamo incontrato al Problema n.5. Adesso sono permesse le connessioni all'interno dello stesso dominio ma abbiamo ancora bisogno di usare la network wildcard per le connessioni ad altri domini.

Adesso stiamo andando da qualche parte: mostriamo la pagina in cache solo se non ha successo la pagina normale.

Usare ApplicationCache solo per il contenuto statico

Con “contenuto statico” intendo il contenuto che non cambia mai: immagini, script, stili e la nostra pagina di fallback.


CACHE MANIFEST

js/script-v1.js
css/style-v1.css
img/logo-v1.png

FALLBACK:
/ fallback/v1.html
/imgs/avatars/ imgs/avatars/default-v1.png

Se avessimo bisogno di fare un cambiamento al JavaScript, dovremmo caricare un nuovo file su un nuovo url, ad esempio, script-v2.js

Questo aggira i Problemi n.1 e n.2: all'utente non verrà mai mandato uno script o uno stile non aggiornati perché ci sarà un nuovo url quando cambierà. Non dobbiamo gestire nel manifest dei numeri di versione basati sui commenti perché il cambiamento del testo nell'url è sufficiente per azionare un aggiornamento. Tutte le risorse avranno una cache orientata al futuro, quindi solo i file modificati avranno bisogno di una richiesta http per aggiornarsi.

Problema n.6: addio download condizionali!

Dai, non avrete davvero pensato che questo sarebbe stato un articolo senza nemmeno un riferimento al responsive design!

Avete due insiemi di immagini di design? Uno di questi è molto più piccolo e più leggero, pensato apposta per le persone che vedono il sito un dispositivo mobile? Usate le media query per decidere quale di queste mostrare? Bene, ApplicationCache odia voi e la vostra famiglia.

Tutte le immagini necessarie per visualizzare il vostro sito vanno nel manifest e il browser le scarica tutte. Nel caso delle immagini responsive, l'utente finisce con lo scaricare entrambe le versioni della stessa risorsa: viene così vanificato qualsiasi sforzo. Usate semplicemente le immagini a risoluzione desktop e ridimensionatele sul client usando CSS background size.

Se la versione mobile ha un design completamente differente, almeno mettetele in un'immagine sprite insieme alla grafica ad alta risoluzione, così che possano beneficiare insieme dalla compressione png basata sulla palette.

La stessa regola vale per i font. Ho visto degli idioti raccomandare di usare molti formati di font, il che va molto bene per i siti normali, ma non si possono tenere tutti nel manifest. Per l'uso offline, usate solo i True Type Fonts (TTF). “Hey, ma non era Web Open Font Format (WOFF) il futuro?” Sì, probabilmente, ma solo per ragioni legali. Non c'è nessun beneficio tecnico derivante dall'uso di WOFF piuttosto che di TTF. Ok, WOFF ha la compressione built-in, ma non è migliore della versione “gzipped” di un TTF. Inoltre, WOFF non è supportato dalle versioni più vecchie di molti browser, mentre il supporto per TTF si estende ben oltre.

Comunque, torniamo ad ApplicationCache.

Usare LocalStorage per mettere offline dinamicamente

Non possiamo mettere offline tutto il nostro contenuto, perché ce n'è troppo. Vogliamo che l'utente scelga a cosa vuole accedere offline. Possiamo usare LocalStorage per memorizzare i dati.

Sì, LocalStorage è solo uno scaffale, ma è uno scaffale estremamente utile e molto semplice da usare. Potete metterci qualsiasi dato testuale che volete e prenderlo poi dopo, da qualunque pagina dello stesso dominio.

LocalStorage è memorizzato sul disco, quindi usarlo è economico ma non gratis. A causa di ciò, dovremmo tenere il numero di letture e scritture basso e non vogliamo leggere e scrivere di più di quello che dovremmo per ogni read/write.

Useremo una entry per ogni pagina che memorizziamo e una entry aggiuntiva per tener traccia di quello che abbiamo salvato offline, insieme ai rispettivi titoli di pagina. Questo significa che possiamo elencare tutte le pagine che abbiamo memorizzato con una sola lettura e mostrare una pagina particolare con due letture.

Così, per salvare la pagina articles/1.html per l'utilizzo offline, facciamo così:


// Get the page content
var pageHtml = document.body.innerHTML;
var urlPath = location.pathName;
// Save it in local storage
localStorage.setItem( urlPath, pageHtml );
// Get our index
var index = JSON.parse( localStorage.getItem( index' ) );
// Set the title and save it
index[ urlPath ] = document.title;
localStorage.setItem( 'index', JSON.stringify( index ) );

Poi, se l'utente visita articles/1.html senza una connessione, otterrà fallback.html, che fa quanto segue:


var pageHtml = localStorage.getItem( urlPath );
if ( !pageHtml ) {
	document.body.innerHTML = '<h1>Page not available</h1>';
}
else {
	document.body.innerHTML = localStorage.getItem( urlPath );
	document.title = localStorage.getItem( 'index' )[ urlPath ];
}

Possiamo iterare localStorage.getItem( 'index' ) per ottenere i dettagli su tutte le pagine che l'utente ha messo in cache.

Mettiamo tutto insieme

Ecco una demo in azione di quanto illustrato sopra. Le pagine dell'articolo possono essere messe in cache mediante un pulsante nel lato in alto a destra della pagina e la pagina index indicherà quali pagine sono disponibili offline.

Tutto il codice è disponibile su GitHub. Qualunque pagina può essere messa in cache con una chiamata a offliner.cacheCurrentPage(). Questa viene richiamata a ciascuna visita alla pagina index e durante ogni visita a una pagina che l'utente desidera mettere in cache.

Se l'utente finisce sulla pagina di fallback, viene richiamata offliner.renderCurrentPage(), che rende la pagina desiderata. Se non abbiamo una pagina da mostrare, viene visualizzato un messaggio. Oh, questo mi ricorda il...

Problema n.7: non sappiamo come siamo arrivati alla pagina di fallback.

Quando non possiamo visualizzare una particolare pagina, l'errore che mostriamo è piuttosto vago. Stando alla specifica, la pagina di fallback viene visualizzata se la richiesta originale risulta in “un redirect a una risorsa con un'altra origine (indicativa di un portale catturato), o un codice di stato 4xx o 5xx o equivalente, oppure se ci sono stati errori di rete (ma non se l'utente ha cancellato il download).”

Per certi aspetti si tratta di una buona notizia: se l'utente è online ma il nostro sito va giù, il loro browser gli mostrerà semplicemente i dati messi in cache e l'utente potrebbe non accorgersene nemmeno! Sfortunatamente, non abbiamo accesso alla ragione del fallback. Potrebbe essere causato dal fatto che l'utente non ha connessione, potrebbe essere che abbiano seguito un url rotto o averlo scritto male, oppure potrebbe essere colpa del server. Semplicemente, non lo sappiamo.

Oh, avete notato l'accenno ai redirect?

Problema n.8: i redirect ad altri domini sono trattati come un errore.

Sì, corretto, un altro problema. Sono sorpreso che stiate ancora leggendo. Se volete andare a chiudervi nel cubicolo di una toilette e rifiutarvi di uscirne finché non sarà sparito internet, vi capirei perfettamente.

Se uno dei vostri url decide di aver bisogno di fare redirect a Twitter o Facebook per fare un'autenticazione, il nostro amichevole Application Cache deciderà che NON È POSSIBILE e ci mostrerà al suo posto la nostra pagina di fallback.

Questa regola ha dei buoni presupposti: se l'utente cerca di visitare il vostro sito e il wi-fi che stanno usando li ridirige a http://rubbish-network/pay-for-wifi-access, mostrando al suo posto la nostra pagina di fallback, allora è grandioso.

Nel caso dei redirect intenzionali e spontanei per delle autorizzazioni, non funziona elencarli nella sezione NETWORK. Al contrario, dovete usare un JavaScript o un meta-redirect. Acc!

Gli svantaggi dell'approccio LocalStorage

“Ah, siamo passati agli svantaggi adesso? E cos'era esattamente il resto dell'articolo?” Sì, lo so, non picchiatemi! Ci sono degli svantaggi rispetto alla semplice soluzione di ApplicationCache.

Occorre JavaScript, mentre invece l'uso di ApplicationCache per Sprite Cow non è dipendente da JavaScript (sebbene il resto del sito lo sia). Mi esporrò alle critiche e vi dirò che ci sono molti pochi utenti che supportano ApplicationCache e che non supportano JavaScript. Questo non vuol dire che l'assenza di supporto per JavaScript non sia importante: il sito mobile di Lanyrd funziona senza JavaScript. Infatti, evitiamo il parsing di JavaScript sui dispositivi più vecchi per far sì che le cose rimangano semplici e rapide.

L'esperienza su una cattiva connessione non è fantastica: il problema con FALLBACK è che la connessione originale deve cadere prima che possa avvenire un qualsiasi fallback, cosa che richiede del tempo se la connessione va e viene. In questo caso, il Problema n.1 )i file arrivano sempre da ApplicationCache) è piuttosto utile.

Non funziona su Opera. Opera non supporta correttamente le sezioni FALLBACK nei manifest. Speriamo che lo sistemino presto questo problema.

Cosa fa di diverso m.lanyrd.com?

La demo che ho mostrato in precedenza è una semplificazione di quello che facciamo a Lanyrd. Invece di memorizzare l'HTML della pagina per l'utilizzo offline, memorizziamo i dati JSON in LocalStorage e i template per quei dati in ApplicationCache. Questo significa che possiamo aggiornare i template in maniera indipendente dai dati ed usare un insieme di dati in più template.

I nostri dati JSON sono versionati per conferenza. Questi numeri di versione vengono controllati quando navigate nel sito. Se non corrispondo a quelli che avete memorizzato, viene scaricato un aggiornamento. Ciò significa che fate solo una richiesta per i dati aggiornati quando c'è un aggiornamento.

Piuttosto che dare un pulsante che permetta all'utente di memorizzare offline una particolare pagina, mettiamo in cache i dati degli eventi che l'utente segue o a cui partecipa. Come risultato, il server sa quello che l'utente vuole offline, quindi se cambiano dispositivo o se perdono in qualche modo la propria cache, possiamo rapidamente ripopolarla.

Lo scambio delle pagine è fatto con XMLHttpRequest e pushState: è molto più rapido su device mobile perché non deve rianalizzare il JavaScript ad ogni caricamento di pagina e la fa sembrare più una app che un sito.

Oh, per l'amor dei tempi andati, vai avanti!

Problema n.9: un balzo in più per saltare attraverso XHR.

Potete fare delle richieste XHR per le risorse mentre siete offline. Sfortunatamente, le versioni più vecchie di WebKit terminano la richiesta con uno statusCode pari a 0, che le librerie più popolari interpretano come un errore.


// In jQuery...
$.ajax( url ).done( function(response) {
	// Hooray, it worked!
}).fail( function(response) {
	// Unfortunately, some requests
	// that worked end up here
});

Allo stato brado, potete vedere questo su Blackberry Playbook e sui dispositivi che usano iOS3 e Android 3/4. Il browser di Android 2 non ha questo baco. Strandamente, sembra che utilizzi una versione più nuova di WebKit. Supporta anche history.pushState mentre al contrario i browser sulle versioni successive di Android non lo fanno. GRAZIE ANDROID. Ecco come aggirare questo problema:


$.ajax( url ).always( function(response) {
	// Exit if this request was deliberately aborted
	if (response.statusText === 'abort') { return; }

	// Does this smell like an error?
	if (response.responseText !== undefined) {
		if (response.responseText && response.status < 400) {
			// Not a real error, recover the content
			response = response.responseText;
		}
		else {
			// This is a proper error, deal with it
			return;
		}
	}

	// do something with 'response'
});

Ed ecco una demo su cui potete fare un po' di test.

ApplicationCache: il vostro amico idiota

Non sto dicendo che ApplicationCache debba essere evitato: è estremamente utile. Conosciamo tutti qualcuno che si loda un po' o che ha bisogno di più “attenzioni” degli altri in caso facciano qualcosa di molto stupido. ApplicationCache è una di quelle persone.

ApplicationCache può, dopo attente istruzioni, fare cose che altri non riescono a fare. Ma quando dice “Non dovete chiamare un idraulico, vi sistemo io il vostro bagno! Ho fatto tutti i bagni a Buckingham Palace, sai?”, lasciatelo perdere.

Se state creando una qualsiasi cosa più complicata di un'“app” indipendente a lato client, passerete dei bei momenti usandola al suo minimo assoluto e facendo fare tutto il resto a LocalStorage.

Illustrazioni: Carlo Brigatti

Share/Save/Bookmark
 

Discutiamone

Ti sembra interessante? Scrivi tu il primo commento


Cenni sull'autore

Jake Archibald

Jake ArchibaldJake Archibald è uno sviluppatore in Lanyrd specializzato in cose client-stuff, sebbene si interessi un po' di Django. Ha creato la mobile web app di Lanyrd con l'ambizioso scopo di essere supportata da più device piuttosto che "per il solo Webkit, grazie". È appassionato di web performance, dello sviluppo di Sprite Cow per aiutare ad alleviare il dolore derivante dagli sprite sheets. Al di fuori del web, gli piace il sapore della birra, guardare la Formula Uno e fare foto alle cose. La sua ambizione è quella di diventare fashion designer.

Questo sito per poter funzionare utilizza i cookie. Per saperne di più visita la pagina relativa all' INFORMATIVA