“Put the burden on the client”…

Qualche tempo fa ho avuto un’interessante discussione sul tema della comunissima comunicazione fra webserver e browser. Nulla di trascendentale ma la discussione si è rapidamente polarizzata sul carico di lavoro per i due interlocutori.

In sostanza: chi si deve sobbarcare il grosso del lavoro fra client e server?

Formattazione? No grazie!

Per “grosso del lavoro” intendo produrre i dati e formattarli/strutturarli in modo da renderli trasmissibili e facilmente utilizzabili. Secondo una certa ottica il server, normalmente ben corazzato, è più che in grado di elaborare dati e restituire comodamente al client la pappa pronta, ad esempio risposte sotto forma di pagine HTML o XML complete.

Il problema è che il server, come entità-simbolo, dovrebbe puntare a fornire in fretta le informazioni e chiudere quanto prima la connessione, non “perdere tempo” a preparare la pappa pronta per il client: meno tempo il server ci mette a trattare con un singolo client, più richieste potrà evadere.

Il tutto si traduce in risparmio di:

  • risorse: non appena un client è stato servito, le risorse impiegate per gestire la connessione con esso saranno immediatamente riusabili per gestirne un’altra nuova;
  • banda: trasferendo solamente i dati, magari strutturandoli in modo poco prolisso (es: JSON invece di XML), si ottiene un’occupazione di banda contenuta, che fa comodo sia al server che al client.

Dal libro “Release It!” di Michael T. Nygard, nella sezione dei capacity antipattern:

Response Formatting

“Do not return HTML pages or fragments. HTML is needlessly verbose; it wastes bandwidth. Instead, return just the data—without formatting—that the client can use to dynamically update the elements on the page.

Use JavaScript object notation (JSON) for data, rather than XML. I know XML is in the name, but that’s mainly because it makes a catchier buzzword than “AJAS” would. JSON is much easier to parse in the browser and can be a lot less verbose (reducing bandwidth consumption).”

Mi piace vedere il tutto come una rielaborazione in chiave funzionale/per-ruoli del pattern MVC:

  • il model – nella fattispecie i dati essenziali -, il minimo essenziale di controller vengono gestiti dal server, che applica anche la parte più importante logica di controllo;
  • la view, una parte del controller nonché la parte della logica di controllo/funzionamento che si può far eseguire in modo sicuro al client, interamente a carico del browser.

In altre parole l’app(licazione) è il browser ed il server remoto diventa solo un mero deposito di dati. Tutto ciò che si può far fare al client in modo sicuro, glielo si deve far fare, badando ovviamente a non sovraccaricarlo troppo.

Il mito del client “thin”

Siamo nel 2011 e sono veramente pochi i dispositivi così poco potenti da non riuscire a gestire al meglio un browser: salvo certi contesti specifici, il periodo del thin client come paradigma è terminato da un pezzo, almeno dal punto di vista delle prestazioni dei dispositivi.

Assumere che il cliente disponga di qualcosa di prestazionalmente scarso per visitare il nostro sito è un insulto, ad esempio, alla Legge di Moore opportunamente “universalizzata” per abbracciare tutti i tipi di dispositivo (PC desktop, smartphone, tablet…).

Inoltre è anche una forma di inutile ottimizzazione anticipata e, come direbbe Knuth:

“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil”

Per cui pianificare un sito pensando di fornire pagine complete e/o dati già pronti per essere visualizzati in fretta dal browser dell’utente – qualunque dispositivo stia usando – è osservare il problema dal lato sbagliato: ormai i browser sono così ottimizzati che il problema non è più parsare i dati, manipolarli via Javascript e visualizzarli, quanto piuttosto attendere che arrivino.

Continuo ad imbattermi in persone arciconvinte che sia meglio ritornare pagine web complete piuttosto che manipolare pochi dati via Javascript perchè quest’ultimo “è lento”.

Mi spiace, ma gli engine Javascript presenti nei vari browser sono probabilmente fra i compilatori più efficienti in circolazione e continuano a migliorare nel tempo come e più di quelli di molti altri linguaggi di programmazione.

Chi continua ad asserire che Javascript è lento o, peggio ancora, interpretato, evidentemente è rimasto a 10 anni fa. Non a caso ormai si parla di compilatori Javascript, perlopiù JIT, non più di interpreti.

Inoltre – e qui sta il bello – meno tempo il server ci mette a rispondere, meno probabile che l’utente sia portato a pigiare il pulsante di reload di una pagina.

Sempre dal sopracitato libro:

Make the Reload button irrelevant

Fast sites don’t provoke the user into hitting the Reload button. You want your site to serve pages so fast that the Reload button never comes into it. Reload requests hurt your site when it’s already suffering.

“Caricare” il client

Morale della fiaba: il server faccia il server.

Il client, come un umano in carne ed ossa in coda ad uno sportello, spesso è più interessato ad avere una risposta che non al contenuto della stessa.

Esempio: aprite una pagina web ma quando è ragionevolmente completa scoprite che in realtà non è ciò che cercavate. E cambiate pagina o sito…

A quel punto il tempo di risposta del sito diventa la parte essenziale del discorso: che importa perdere tempo ad inserire tutti gli orpelli del caso quando poi l’utente, magari, non li guarderà nemmeno?

In sostanza e cinicamente, perchè dovrei spendere tempo e risorse per qualcuno che non è interessato davvero a me e da cui non posso ricavarci nulla? (cioè abbassa o comunque non alza il conversion rate).

Prima lo servo, prima se ne andrà e magari lascerà il posto (e le risorse libere) a qualcuno che è davvero interessato al mio sito e che, magari, riuscirò a trattenere a lungo.

Per cui, nel caso, non credo ci sia nulla di male nel caricare un po’ di lavoro il browser del client: put the burden on the client! Dopotutto è il client a disturbare il server e non viceversa.

Non a caso Google ha da tempo inserito la latenza di risposta/”velocità del sito” fra i criteri di assegnamento del rank.

Che ne pensate?

Contrassegnato da tag , , , , , , , ,

2 thoughts on ““Put the burden on the client”…

  1. RaS! scrive:

    JP ha riscoperto l’acqua calda ma forse il post è rivolto proprio a coloro che ritengono js ancora un chiodo in termini di velocità. E’ palese che per ridurre il payload della pagina, specie su chiamate ajax, conviene ridurre il numero dei dati che si elabora. La serializzazione è fatta apposta!
    Abbiamo un sacco di framework js che abbinati ai plugin più disparati, permettono un’ottima formattazione dei dati col minimo sforzo.

  2. jp scrive:

    @Ras: più la seconda, direi. :) Stessa cosa per quelli de “il server deve essere bello pompato e fare tutto così il client può vivere di rendita“: poi si trovano con qualche centinaia o migliaia di connessioni in parallelo e si stupiscono che il server non ce la faccia e/o la banda non basti… ^^’

    PS: ormai per AJAX mi sono standardizzato su “JSON compresso LZW”, quando non ho a disposizione Gzip ovviamente. :)

    Ciao & grazie di essere passato. ^^

Lascia un Commento

Fill in your details below or click an icon to log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Log Out / Modifica )

Foto Twitter

You are commenting using your Twitter account. Log Out / Modifica )

Foto di Facebook

You are commenting using your Facebook account. Log Out / Modifica )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 259 other followers