informatica

Preistoria delle SPA

Per capire come si e' arrivati agli strumenti client side a cui oggi possiamo attingere, andremo a...

Andrea Scianò Andrea Scianò 27 Dic 2017 · lettura da 25 min
Preistoria delle SPA

In questo post abbiamo cercato di fare il punto sulle SPA (Single Page Application) e tentato di spiegare a grandi linee cosa esse siano. Come avevo anticipato, per capire come si è arrivati agli strumenti client side a cui oggi possiamo attingere, andremo a dare uno sguardo indietro nel passato.

Breve riassunto

È importante ricordare, dato che ne faremo dei riferimenti più avanti, che con comunicazione client-server (letteralmente cliente-servente) si intende un'architettura di rete nella quale genericamente un computer client o terminale si connette ad un server per la fruizione di un certo servizio, quale ad esempio la condivisione di una certa risorsa hardware/software con altri client, appoggiandosi alla sottostante architettura protocollare. Più semplicemente, i sistemi client/server sono un'evoluzione dei sistemi basati sulla condivisione semplice delle risorse: la presenza di un server permette ad un certo numero di client di condividerne le risorse, lasciando che sia il server a gestire gli accessi per evitare conflitti di utilizzazione tipici dei primi sistemi informatici.

Come abbiamo detto un’applicazione a pagina singola è un'applicazione web che richiede il caricamento di una sola pagina all’interno del browser web. Questa è una definizione molto comoda e concisa per rendere l’idea ma merita delle chiarificazioni. Applicazione web è un termine altrettanto generico, possiamo avere un’applicazione web che sia semplicemente un sito web statico formato da una manciata di pagine, oppure possiamo avere un software complesso come Flickr, Google Maps e tantissimi altri. Il concetto di fondo di una SPA è che l’utente debba navigare verso una pagina una sola volta, di conseguenza il browser costruirà la struttura interna della pagina basandosi sul modello a oggetti DOM, una sola volta. Dopo di che JavaScript, che agisce dietro le quinte, stabilisce e gestisce le interazioni con il server e modifica la vista (il view layer) a seconda dei dati che riceve. Pensare all’aggiornamento delle viste ed alla comunicazione con il server come due problemi distinti è una cosa che oggigiorno sembra scontata ma non lo è affatto. Inoltre, dato che il pattern MVC, su cui tutte le SPA si basavano quando sono nate, è presente sin dagli anni '70, perché abbiamo dovuto aspettare il concetto di single page application per poter capire come progettare un’applicazione web? Come spesso accade, la domanda può trovare una risposta se guardiamo al passato, dunque quello che segue è un excursus di come la programmazione web si sia evoluta dai giorni in cui è nata, sino ad oggi. Dal non avere nemmeno uno script e solamente pagine HTML statiche interpretate dai browsers dell’epoca, all’utilizzo di robusti strumenti di ingegneria come i frameworks client side, il tutto nel brevissimo periodo di circa 20 anni. Nei primi anni '90 Internet subì l’impulso per una rapida crescita, causata da una serie di invenzioni elencate di seguito e fortemente legate tra loro, per lo più accreditabili a Tim Berners-Lee, laureato in fisica ed impiegato al CERN di Ginevra durante quegli anni.

HTML - HyperText Markup Language

Nel 1989 Berners-Lee propose un progetto per la condivisione delle informazioni tra la comunità dei fisici delle alte energie, noto con il nome di world wide web (WWW). All'interno di questo progetto in seguito nacquero sia il server web httpd (descritto poco più avanti), sia il client WorldWideWeb (ovvero il primo browser della storia), il cui sviluppo partì nell'ottobre del 1990, ed il cui uso fu esclusivamente interno al CERN sino alla sua pubblicazione in rete nel 1991.

Assistito dai suoi colleghi all'interno dell'istituto Svizzero, Berners-Lee concorse alla definizione della prima versione del linguaggio di markup più famoso che esista: l'HTML, che fu ufficialmente reso pubblico nel giugno del 1993. Un linguaggio di markup è un insieme di regole che descrivono i meccanismi di rappresentazione (strutturali, semantici o presentazionali) di un testo che, utilizzando convenzioni standardizzate, sono utilizzabili su più supporti. La tecnica di formattazione per mezzo di marcatori (o espressioni codificate) richiede quindi una serie di convenzioni, ovvero appunto di un linguaggio a marcatori di documenti. Il termine markup (o marcatura) deriva dall'ambiente tipografico dove si usava marcare con annotazioni le parti del testo che andavano evidenziate o corrette, allo scopo di segnalarle al compositore o al dattilografo. Attenzione a non confondere un linguaggio di markup con un linguaggio di programmazione, visto che si tratta di due realtà ben diverse. L’HTML non può essere ritenuto un linguaggio di programmazione perché, anche se oggi supporta l’inserimento di oggetti esterni come filmati e immagini, non presuppone alcuna definizione di strutture di controllo, di funzioni, di strutture dati o di variabili in grado di realizzare programmi. Nel 1994 il linguaggio ebbe una forte diffusione in seguito ai primi utilizzi commerciali del web, così nello stesso anno nacque il World Wide Web Consortium, e da quel momento in poi, lo sviluppo dell'HTML diverrà prerogativa del W3C. Di seguito, un esempio di una semplicissima pagina HTML che visualizza il testo “Ciao mondo” nella finestra di un browser.

<html>
    <head>
        <title>
            Semplice pagina
        </title>
    </head>
    <body>
        <p>Ciao mondo</p>
        <a href="www.sciano.net">Cambia pagina</a>
    </body>
</html>

Come si può notare, un documento web consiste di elementi ed entità: • L’elemento html identifica le componenti del documento, per esempio il corpo del documento (body), l’elemento paragrafo (p) e l’elemento ancora (a). • Alcuni elementi hanno un tag di apertura (per esempio <body>) ed un tag di chiusura (per esempio </body>). Per alcuni, il tag di chiusura è opzionale e non necessario. • Il tag <head> è univoco (specificabile una ed una sola volta) per ogni pagina e definisce l'header (intestazione) della pagina. Va aperto subito dopo l'apertura del tag html e chiuso subito prima dell'inizio del corpo della pagina indicato dal tag <body>. Anche quest’ultimo è univoco e va aperto dopo la chiusura dell’header e chiuso prima della chiusura del tag <html>, esso costituisce il corpo della pagina. • All'interno dell'header è possibile inserire il <title> (titolo) della pagina, ma anche vari script, indicazioni di stili grafici che comunicano al browser come deve essere visualizzata la pagina (chiamati stili CSS) e i meta tag, in modo da far si che vengano eseguiti prima del caricamento della pagina. • Alcuni elementi HTML hanno attributi opzionali che specificano la funzione dell’elemento stesso, ad esempio l’elemento <a> possiede un attributo href che identifica l’URL a cui l’ancora punta se viene cliccato.

HTTP - HyperText Transfer Protocol

È un protocollo a livello applicativo usato come principale sistema per la trasmissione di informazioni in un'architettura tipica client-server. La prima versione dell'HTTP, la 0.9, risale alla fine degli anni ‘80 e costituiva, assieme al linguaggio HTML ed agli URL, il nucleo base del World Wide Web. La prima versione effettivamente disponibile del protocollo, la HTTP/1.0, venne implementata dallo stesso Berners-Lee nel 1991 e proposta come RFC 1945 all'ente normatore IETF nel 1996.

URL - Uniform Resource Locator

Nella terminologia delle telecomunicazioni e dell'informatica, è una sequenza di caratteri che identifica univocamente l'indirizzo di una risorsa in Internet, tipicamente presente su un server, come ad esempio un documento, un'immagine, un video, rendendola accessibile ad un client. L'URL di solito è una sequenza di caratteri indipendente dal web, ed anche se il tipo più comune identifica risorse web utilizzando il protocollo http, è altresì vastamente utilizzata per indicare risorse accessibili tramite protocolli di trasferimento file (ftp), condivisioni remote (smb), o accessi a sistemi esterni (ssh). La struttura di un URL è codificata nel documento RFC 3986 della IETF, e si compone normalmente di sei parti, alcune delle quali opzionali:

protocollo://[username:password@]host[:porta]</percorso>[?querystring][#fragment]

  1. protocollo identifica il protocollo da utilizzare per l'accesso al server. Se il protocollo non viene specificato, generalmente il browser utilizza il protocollo http come predefinito.

  2. :// è il separatore tra il protocollo ed il resto dell'URL, di solito l'host, o opzionalmente lo username.

  3. username:password@ è opzionale, per questo motivo indicato tra parentesi quadre. Subito dopo il protocollo, è possibile specificare le credenziali di autenticazione per l'accesso alla risorsa. L'autenticazione in URL è però estremamente rischiosa, in quanto le credenziali di accesso vengono inviate al server in chiaro, ovvero non cifrate.

  4. host identifica il server su cui risiede la risorsa. Può essere rappresentato direttamente da un indirizzo IP o, più comunemente, da un nome di dominio che il software converte in indirizzo IP avvalendosi del servizio DNS.

  5. :porta (opzionale) identifica la porta del servizio di rete al quale inoltrare la richiesta. Il numero di porta può essere omesso quando corrisponde alla porta standard associata al protocollo indicato dall'URL (ad esempio 80 per HTTP o 443 per HTTPS).

  6. percorso (opzionale) indica la locazione nel file system del server che identifica la risorsa.

  7. querystring (opzionale) al termine dell'URL è possibile aggiungere una query string separandola con l'utilizzo del simbolo ?. La query string è una stringa di caratteri che consente di passare al server uno o più parametri.

  8. fragment (opzionale) se presente, indica una parte o una posizione all'interno della risorsa

HTTPD - Hypertext Transfer Protocol Daemon:

È il primo server web di base, in realtà un semplice software che viene eseguito in background e rimane all’ascolto di richieste in entrata. Il demone risponde a tali richieste automaticamente, e serve gli ipertesti o i documenti multimediali utilizzando il protocollo http.

L’evoluzione

Gli strumenti presentati precedentemente sono esposti ed usati dai browser web, che sanno come ottenere pagine HTML da URL tramite il protocollo HTTP e sanno come interpretare graficamente le informazioni, visualizzandole sul monitor dei nostri computer. Notevoli browser dell’epoca sono, come abbiamo detto, WorldWideWeb del 1991, ma anche Mosaic del 1993 e Netscape nel 1994.

Per il proseguimento del discorso è importante però definire l’accezione di pagina. Ai fini di questa discussione la parola pagina assume due significati principali:

  1. Il documento ricevuto dal browser specificato da un URL e mostrato all’utente.

  2. Il contenuto all’interno della finestra del browser che si può osservare in un certo istante.

Quest’ultimo punto è, nell’immaginario comune, le definizione attuale di pagina web. La prima asserzione invece, è la definizione originale di pagina web. Ogni view, dai primi anni ‘90 agli albori di internet, è un file HTML che vive su di un server ed è una risorsa recuperabile ed accessibile tramite un URL. Ma se ci facciamo caso, il punto 1 è anche la definizione prevista per una Single Page Application! Possiamo dunque notare che essa è definita in termini di ambiente in cui vive, ma non è stata creata per tale scopo! In quegli anni gli sviluppatori di siti web più sofisticati mettevano insieme pagine HTML collegate tra loro tramite link ipertestuali, modificavano file statici sul server o li caricavano tramite ftp. La cosa più simile alle SPA erano le applicazioni desktop.

Nascita di JavaScript e miglioramenti server side

JavaScript è stato creato da Netscape nel 1994 e commercializzato come fratello minore di Java. Deve il suo nome al cambio effettuato nel periodo in cui Netscape stava includendo il supporto alla tecnologia Java nel suo browser, Netscape Navigator prima era chiamato LiveScript. La scelta del nome si rivelò fonte di grande confusione dato che non c'è una vera e propria correlazione tra Java e JavaScript; le loro somiglianze sono soprattutto nella sintassi (derivata in entrambi i casi dal linguaggio C); le loro semantiche sono piuttosto diverse, ed i loro object model non hanno relazione e sono ampiamente incompatibili. Inoltre JS è un linguaggio di scripting che viene inserito dentro la pagina HTML all’interno del tag <script> come nell’esempio:

<html>
   <head>
       <title>Esempio funzione JS dentro HTML</title>
       <script type="text/javascript">
           function cliccato() {
               alert(‘Bottone cliccato!’);
           }
       </script>
   </head>
   <body>
      <input type="button" onclick="cliccato();" />
   </body>
</html>

In questo caso una volta fatto click sul bottone, viene creato un evento chiamato appunto click. È possibile associare una funzione ad ogni evento che si può verificare, nello specifico assegnando la funzione cliccato() al verificarsi dell’evento click con la linea di codice onclick="cliccato();" stiamo dicendo che vogliamo tale funzione eseguita ogni qual volta che quel bottone viene cliccato. In questa situazione, quello che poi farà la funzione sarà stampare in una finestrella il testo “Bottone cliccato”.

L’utilizzo di JavaScript non si diffuse fin da subito, lo script più comune su Internet per un decennio fu qualcosa come:

// Funzione che mostra la stessa immagine
// ma ingrandita passando sopra col mouse

element.onmouseover = function () {
    document.getElementById("anImage").src = "anImageBigger.jpg";
}

Durante questo periodo primordiale, le cose più complicate fatte con JavaScript erano i rollover dei menu, i ticker (quelle frasi che si scrivevano da sole), i timer e quelle scimmiette inquietanti le cui pupille seguivano il cursore del mouse in ogni direzione dello schermo.

Non dobbiamo però mai dimenticarci di contestualizzare, ed anche se le cose appena affermate possono sembrare ambigue ad un lettore che non ha vissuto quei tempi, ricordiamo che le macchine client side erano considerate come dei terminali all’epoca, per niente simili ai PC che utilizziamo oggi. Al tempo, i server stavano in costose centrali e si puntava su di loro, era lì che iniziavano a nascere possibilità di mostrare qualcosa ai client in modo dinamico. Proprio per questo motivo, furono anni di grande fervore per le tecnologie sviluppate lato server, di seguito ne elencheremo tre fra le più importanti e che hanno influenzato, ognuna a loro modo, la nascita delle SPA:

  1. CGI - Common Gateway Interface: è una tecnologia standard usata dai web server per interfacciarsi con applicazioni esterne generando contenuti web dinamici. Ogni qual volta un client richiede al web server un URL corrispondente ad un documento in puro HTML, gli viene restituito tale documento statico (come un file di testo); se l'URL corrisponde invece ad un programma CGI, il server lo esegue in tempo reale, generando dinamicamente informazioni per l'utente. Dunque, anziché avere un server web che fornisce un file statico, ora si può interrogare un database, eseguire un algoritmo che utilizza la CPU e generare una pagina HTML che contiene, ad esempio, i dati specifici del cliente.

  2. Moduli Apache: il server Apache in questo periodo storico cresce velocemente superando l’httpd che abbiamo descritto precedentemente, diviene rapidamente il server web più utilizzato al mondo. Come molti altri software in veloce crescita, è supportato da un design plugin-friendly offrendo la possibilità di integrare innumerevoli tool aggiuntivi, portando ad utilizzarlo come piattaforma per un intero ecosistema di funzionalità personalizzate lato server. Molti sviluppatori web alla fine degli anni ‘90 svilupparono svariati moduli Apache, dall'autenticazione utente a quelli per il supporto alla lingua.

  3. Linguaggi lato server: le persone si rendono conto che è facile distinguere le parti dinamiche da quelle statiche all’interno di un documento HTML. Un modo per farlo è utilizzare un programma che, preso in input un file simile all’HTML ma con l’aggiunta di diversi tag e stringhe non appartenenti al linguaggio di markup, lo elabora prima di inviarlo al browser. L’esempio più diffuso di linguaggio per lo sviluppo di pagine dinamiche basato su tecnologia server-side è PHP, che permette di scrivere script direttamente nel body delle pagine web, di definire funzioni che eseguono compiti complessi o generare oggetti. Di seguito vediamo come combinare HTML e PHP insieme con un un semplice esempio:

<?php
    $mele = 4;
    $euro = 0.5;

    function calcolaSpesa($quantita, $prezzo) {
        return $quantita * $prezzo;    
    }
?>
<html>
    <head>
        <title>PHP e HTML</title>
    </head>
    <body>
        La mamma ha comprato <?php echo $mele; ?>.
        Ognuna costa <?php echo $euro; ?> Euro.
      Totale spesa: <?php echo calcolaSpesa($mele, $euro); ?> Euro!
    </body>
</html>

Le variabili sono uno degli strumenti fondamentali di ogni linguaggio di programmazione. Una variabile è una porzione di memoria in cui viene memorizzato un dato che può variare durante l’esecuzione del programma. Le variabili in PHP sono delimitate dal carattere $, seguito da un carattere alfabetico o da un underscore. I caratteri successivi al secondo possono contenere qualsiasi sequenza di cifre, caratteri alfabetici ed underscore. Come vedete, abbiamo definito il valore delle variabili $mele ed $euro all‘interno di una porzione di codice PHP che abbiamo posizionato all‘inizio del documento. Molto spesso abbiamo bisogno di stamparne il contenuto di una o più, a video. Il costrutto più importante per poterlo fare è echo. Possiamo anche passare il risultato di un’espressione direttamente al costrutto senza salvarlo prima in un’ulteriore variabile, proprio come abbiamo fatto nel nostro esempio richiamando la funzione calcolaSpesa all‘interno del documento HTML usando una semplice sintassi: <?php echo calcolaSpesa($mele, $euro); ?>.

Infine, possiamo complicare leggermente l’esempio aggiungendo costrutti del linguaggio poco più avanzati per fornire l’idea di cosa si possa fare in ambiti reali. Ecco un altro stralcio di codice per visualizzare gli acquisti effettuati da un ipotetico cliente:

<?php
    $nomeCliente = “Andrea Scianò”;
    $acquisti = [“Nutella”, “Pizza”, “Pasta”];
?>
<html>
    <head>
        <title>Acquisti cliente</title>
    </head>
    <body>
        <h1>Acquisti di <?php echo $nomeCliente; ?></h1>
        <ul>
          <?php foreach ($acquisti as $singoloAquisto) {?>
            <li><? php echo $singoloAquisto; ?></ Li>
    <?php}?>
        </ul>
    </body>
</html>

Vorrei sottolineare che nella realtà, le variabili assumono valori che possono essere la conseguenza di un’interrogazione ad un database o derivanti da altri fattori esterni, molto spesso non sono inizializzate direttamente da noi come nell’esempio appena riportato.

Per simulare ciò, la variabile $acquisti, al contrario di quanto fatto sino ad ora, non è una variabile semplice ma è un array: gli array, presenti praticamente in tutti i linguaggi di programmazione, sono ispirati alla nozione matematica di vettore (quando monodimensionali) o di matrice (nel caso di array bidimensionali). L'array è in genere classificato come un costruttore di tipo: in altre parole, esso consente di definire nuovi tipi di dati a partire da tipi preesistenti, attraverso l'aggregazione di diversi oggetti tutti di uno stesso tipo. Ciascun oggetto componente è individuato attraverso un indice intero, nel caso monodimensionale, o attraverso N indici interi nel caso N-dimensionale. Si può immaginare un array come una sorta di contenitore, le cui caselle sono dette celle (o elementi) dell'array stesso. Ciascuna delle celle si comporta come una variabile tradizionale; tutte le celle sono variabili di uno stesso tipo preesistente, detto tipo base dell'array. Si parlerà perciò di tipi come array di interi, array di stringhe, array di caratteri e così via.

Quello che si ottiene dichiarandolo è dunque un contenitore statico ed omogeneo di valori, variabili o oggetti. Ciascuna delle celle dell'array è identificata da un valore di indice. L'indice è generalmente numerico e i valori che gli indici possono assumere sono numeri interi contigui che partono da 0. In PHP è possibile utilizzare anche indici di tipo stringa, ed il lettore esperto potrà osservare che in questo linguaggio non esiste il vincolo di un tipo base fissato per tutte le celle dell'array essendo esso un linguaggio non tipato.

Lo scopo del foreach invece è quello di costruire un ciclo che viene ripetuto per ogni elemento dell‘array passato. L’esempio presentato stamperà a video in una lista formattata con l’HTML tutti gli acquisti effettuati dal cliente, in quanto il nostro ciclo eseguirà su ogni elemento dell’array l’operazione di stampa con echo. Esistono poi altri importanti costrutti come le strutture di controllo if-else, differenti tipi di cicli e strutture dati interessanti che non andremo a spiegare qui in quanto l’obiettivo era quello di dare un’idea del funzionamento del linguaggio e non una guida dello stesso. Si può creare codice lato server come quello che abbiamo mostrato utilizzando PHP dal 1994, ma anche con i simili ASP dal 1996 e JSP dal 1999.

Tutto questo cambiamento prende il nome di Web 2.0: termine con il quale si pone l'accento sulle differenze rispetto al cosiddetto Web 1.0, diffuso fino al periodo storico appena citato, composto come abbiamo detto da siti web statici, senza alcuna possibilità di interazione con l'utente eccetto la normale navigazione ipertestuale tra le pagine.

Java Applets e Macromedia Flash

Esistono effettivamente software web simili alle moderne SPA a partire dalla metà degli anni '90, due tecnologie introdotte rispettivamente nel 1995 e nel 1996: le applets Java e Macromedia Flash.

Nel periodo storico che stiamo prendendo in considerazione, in tempi in cui la potenza dei server rappresentava un costo ragguardevole e le potenzialità di internet apparivano notevoli ma ancora inespresse, le applets Java diventarono la soluzione ottimale per migliorare aspetto, interattività e popolarità dei siti web.

Macromedia Flash era invece l’opzione più popolare ed era alla base di alcuni dei portali web più interessanti. Era possibile creare siti di grande impatto visivo, completi di barre di caricamento, effetti sonori e transizioni animate tra le pagine.

Anche se questi strumenti contenevano già allora il concetto di pagina singola (tutto il contenuto caricato completamente una volta sola o ottenuto on-demand e sintetizzato nella vista) queste soluzioni non erano facilmente adottabili da tutti per via della loro curva d’apprendimento troppo alta, ma ancora peggio per il fatto che i browser erano trattati semplicemente come proxy verso piattaforme di terze parti, le quali dovevano essere installate esplicitamente da parte degli utenti. Ne consegue che le antenate delle attuali SPA potevano essere diffuse solamente in base a quanto fossero diffuse le piattaforme da cui dipendevano. Ad eccezione di un paio di piccoli ecosistemi esclusivi, a cavallo del millennio la programmazione web è ancora molto legata al vecchio modo di pensare alle pagine: una pagina è ciò che un server web invia al mio browser ed è equivalente a ciò che vedo all'interno della sua finestra in quell’istante. La maggior parte delle innovazioni per le web app avvengono lato server e, nei primi anni 2000, le prospettive di crescita client side sono davvero scarse. Come riferimento temporale possiamo prendere la bolla delle dot-com, appena esplosa, e c'è una mancanza di accordo tra le compagnie creatrici dei browser più in voga in quel momento su come JavaScript debba essere standardizzato e implementato.

La svolta: un nuovo approccio con AJAX

All’alba del nuovo millennio, un'API poco conosciuta chiamata XMLHTTPRequest (oppure con il diminutivo XHR) si fa strada nei web browser più diffusi del momento. Offre un modo sistematico per inviare richieste HTTP ai server e gestire le risposte che si ottengono. Sebbene dal nome possa sembrare scontato che il formato dei dati scambiati sia in XML, in realtà non è l’unico possibile, si possono scegliere vari tipi di dati, inclusi JSON e HTML. Ecco un banale esempio di uso dell’API mediante JavaScript:

// Inizializza la richiesta con metodo da
// utilizzare e url a cui inviarla
var richiestaHTTP = new XMLHTTPRequest();
var metodo = ‘GET’;
var url = ‘http://nomesito.it’;

richiestaHTTP.open(metodo, url);

// Una volta ottenuta la risposta dal server, la funzione
// passata all’evento onload verrà eseguita
richiestaHTTP.onload = function () {
    // Qui abbiamo i dati di risposta dal server
    // con cui possiamo fare ciò che vogliamo
};

// Invia la richiesta
richiestaHTTP.send();

Se questa funzionalità sembra oggi banale, tale supporto da parte dei browser apre un nuovo mondo agli sviluppatori del tempo: client e server web ora possono mantenere attivo un canale di comunicazione che non sia fatto di soli collegamenti ipertestuali e click. Tuttavia, XHR non si diffuse prima del 2005, quando Jesse James Garrett, fondatore di Adaptive path, pubblica un importantissimo documento intitolato “Ajax: A New Approach to Web Applications”.

Nel paper si conia l’accattivante termine AJAX che sta per Asynchronous JavaScript and XML (JavaScript ed XML asincroni). Come suggerisce il titolo, AJAX non è un linguaggio o una tecnologia, è solamente un nuovo modo di progettare applicazioni web che utilizzano varie tecnologie già esistenti. In quegli anni il mantra di Garrett è: usare XMLHTTPRequest per parlare in modo asincrono ad un server, "in background" mentre l’utente utilizza l’interfaccia indisturbato all'interno del browser.

Tali tecniche erano da poco in uso già in alcuni grandi progetti commerciali, in particolare GMail, Google Groups, Google Suggest e Google Maps. Lo stesso Garrett li menziona nel suo documento, il quale ha dato una spinta virale a questo paradigma, facendo nascere una serie di nuove pubblicazioni e metodologie al riguardo, con persone che finalmente iniziano a pensare in modo diverso alla programmazione web. Ci troviamo d’innanzi alla prima vera pubblicazione di un articolo riguardante un’applicazione a pagina singola.

La diffusione di AJAX è una vittoria per il linguaggio JavaScript perché gli addetti ai lavori si rendono conto che si può utilizzare per creare interfacce utente funzionali al Web 2.0. Ma c'è un inconveniente: JavaScript non fu progettato per l'ingegneria del software, è un linguaggio tipizzato dinamicamente, con un sistema di eredità prototipale particolare, da usare con cautela e basato sulla catena di prototipi, con nessun supporto ufficiale per il packaging del codice. Ciò che nacque come linguaggio di scripting per la decorazione di pagine HTML è ora utilizzato più che mai sia da grandi team di sviluppatori che da smanettoni del "taglia e incolla”, individui non particolarmente tecnici scriventi codice mal performante provando a farlo funzionare per tentativi con il materiale trovato nelle varie risorse sparse in rete, solitamente con fine malevolo. Il risultato è un sacco di opportunità per siti web mal funzionanti e non strutturati.

Per ovviare a questo malcostume, intorno alla metà del 2000 una grande figura, Douglas Crockford, ora senior JavaScript architect presso PayPal, sottolinea ironicamente che è davvero facile scrivere programmi sbagliati o pieni di bug in JavaScript. Crockford combatte per i diritti di JavaScript come linguaggio di programmazione legittimo, usando umorismo e buon senso per aiutare a scrivere codice migliore. Riassumiamo di seguito l’impatto che ebbe Crockford sul linguaggio in questione:

  1. JSON (2001) - JavaScript Object Notation è ora il formato di interscambio dati tra client e server più popolare sul web. Douglas Crockford lo ha basato sul linguaggio JavaScript Standard ECMA-262 3ª edizione dicembre 1999, ma ne è indipendente. La semplicità ne ha decretato un rapido utilizzo specialmente nella programmazione con tecniche Ajax. Il suo uso tramite JavaScript è particolarmente semplice, infatti l'interprete è in grado di eseguire il parsing tramite una semplice chiamata alla funzione eval(). Quanto detto ha contribuito sempre più all’utilizzo di JSON a discapito di XML come formato dei dati nella comunicazione tra client e server. La differenza sta nel fatto che XML è un linguaggio di markup mentre JSON no. Entrambi non hanno un sistema di rappresentazione dei dati binari, per cui è compito del programmatore adottare delle convenzioni appropriate per convertire i dati binari in forma testuale.

  2. JsLint (2002) - è uno strumento di analisi del codice utilizzato nello sviluppo di software per verificare se il sorgente JavaScript è conforme alle regole di codifica. Viene fornito principalmente come strumento online, ma esistono anche adattamenti per riga di comando o integrabili nell’editor che si utilizza per scrivere codice, è il predecessore del popolare JSHint.

  3. JsMin (2003) - minificatore per JavaScript, è un filtro che rimuove i commenti e gli spazi bianchi non necessari dai file. In genere riduce la dimensione dei file della metà, con conseguenti download più veloci. Incoraggia anche uno stile di programmazione più espressivo perché elimina il costo di download di un'auto documentazione pulita e verbosa. Il processo a cui si sottopongono i file viene anche chiamato uglification (in inglese ugly significa brutto, quindi la parola si può tradurre come “processo di imbruttimento”) perché una volta terminato, il codice è pressoché illeggibile. Viene utilizzato in quanto i file che andranno in produzione, non interessa che siano belli da vedere, nessuno dovrà mai leggere o risolvere bug usando quei sorgenti, il loro scopo è che siano il più performanti possibile.

  4. JavaScript: The Good Parts (2008) - non è un manuale che insegna il linguaggio ma è un approfondimento scritto da uno dei grandi maestri di javascript (Crockford appunto). Non serve ad imparare JavaScript dalle basi ma per rifinire e rafforzare i concetti imparati in passato con principi architetturali importanti. Non è consigliabile per un neofita ma rappresenta una catapulta verso i pattern più avanzati di javascript.

L’evoluzione client side

Con JavaScript che guadagna sempre più credibilità come linguaggio per progettare applicazioni di livello, la comunità di sviluppatori inizia a rispondere a sua volta con una varietà di librerie open-source, toolkit e framework. Proprio come accaduto negli anni ’90 con la parte server side, la metà e la fine degli anni 2000 sono caratterizzati dalla rapida crescita delle tecnologie lato client. Di seguito una rapida panoramica delle più diffuse:

  1. Dojo: è una libreria JavaScript modulare ed open source (più precisamente un toolkit JavaScript) progettata per velocizzare lo sviluppo di applicazioni e siti web multipiattaforma basati su Ajax. Creata da Alex Russell, Dylan Schiemann e David Schontzler nel 2004. La Dojo Foundation è un'organizzazione no-profit creata con l'obiettivo di promuovere l'adozione del toolkit.

  2. Prototype: è un framework creato da Sam Stephenson nel febbraio 2005, inizialmente ideato come supporto Ajax per Ruby on Rails. Esso ha come scopo quello di facilitare lo sviluppo di applicazioni web dinamiche. In particolare offre supporto per l'utilizzo di Ajax e della programmazione orientata agli oggetti in JavaScript.

  3. jQuery: creata nel gennaio del 2006 da John Resig, è probabilmente la libreria JavaScript più conosciuta al mondo. Il progetto è tenuto tutt’ora attivo ed in evoluzione da un gruppo di sviluppatori guidato da Dave Methvin. Grandi aziende tra cui Microsoft e Nokia forniscono di serie jQuery sulle proprie piattaforme. Il framework fornisce metodi e funzioni per gestire al meglio aspetti grafici e strutturali come posizione di elementi, effetto di click su immagini, manipolazione del Document Object Model e altro ancora, mantenendo la compatibilità tra browser diversi e standardizzando gli oggetti messi a disposizione dall'interprete JavaScript del browser.

  4. YUI - Yahoo! User Interface Library: è una libreria JavaScript open source, non più disponibile, per la creazione di applicazioni web altamente interattive che utilizzano tecniche come Ajax, DHTML e modifica del DOM. YUI include anche diverse risorse CSS di base. Lo sviluppo iniziò nel 2005, nell'estate dello stesso anno My Yahoo! ed il relativo portale utilizzavano già il framework rilasciato invece per uso pubblico nel febbraio 2006. Nel settembre del 2009 Yahoo! rilascia YUI 3, una nuova versione ricostruita interamente per modernizzare la libreria: tra i miglioramenti vi sono un motore di ricerca selettori CSS come avviene in jQuery, un file principale più piccolo che carica gli altri moduli quando necessario ed una varietà di modifiche sintattiche per rendere la scrittura veloce e semplice. Fondato da Thomas Sha e sponsorizzato dal cofondatore di Yahoo! Jerry Yang, ne viene interrotto lo sviluppo il 29 agosto 2014.

  5. MooTools: creato da Valerio Proietti che lo ha pubblicato nel settembre del 2006 prendendo ispirazione da Prototype, MooTools è nato da Moo.fx, una popolare libreria di effetti JavaScript rilasciata a sua volta nell'ottobre 2005 dallo stesso autore, come componente aggiuntivo del Prototype Javascript Framework. Il progetto è ancora mantenuto ed utilizzato e può essere un’alternativa più leggera di altre librerie. Fornisce effetti semplici di base e garantisce dimensioni ridotte. Mentre Prototype estende molti degli oggetti nativi di JavaScript quali String, Array e Function con metodi aggiuntivi, Proietti desiderava un framework che estendesse ulteriormente anche l'oggetto nativo Element, per offrire un maggiore controllo del DOM.

Tutte le librerie elencate sopra hanno degli elementi in comune, in un modo o nell’altro esse cercano di introdurre tre caratteristiche:

  1. funzioni di utilità che arricchiscono JavaScript
  2. manipolazione del DOM cross-browser
  3. alcuni componenti già pronti da inserire nella user interface utilizzandoli con il minimo sforzo. Alcuni esempi: menu a discesa, caroselli di immagini, tabelle dati, ecc.

La nascita di GitHub

Vale la pena aprire una parentesi sulla nascita di GitHub, che ha avuto un impatto incredibile sulla condivisione del codice. GitHub Inc. viene fondata nel 2008 con il nome di Logical Awesome dagli sviluppatori Chris Wanstrath, PJ Hyett e Tom Preston-Werner, ed è un servizio di hosting per progetti software. Il nome GitHub deriva dal fatto che è un’implementazione dello strumento di controllo versione distribuito Git.

Il servizio è principalmente utilizzato dagli sviluppatori, che caricano il codice sorgente dei loro programmi e lo rendono scaricabile dagli altri utenti. Quest’ultimi possono interagire con lo sviluppatore tramite un sistema di tracciamento dei bug, richieste di modifica del codice e commenti che permettono di migliorare la codebase del repository risolvendo errori o aggiungendo funzionalità.

Il 24 febbraio 2009 i creatori dichiarano che i repository pubblici ammontano a 46.000 , di cui 17.000 creati nei 30 giorni precedenti. Il 5 luglio si raggiungono i 100.000 utenti. Il 27 luglio 2009 i repository pubblici diventano 135.000, 1 milione l'anno successivo e 2 milioni nell'aprile 2011.

Da gennaio 2010 assume ufficialmente il nome di GitHub, Inc.

Il 16 gennaio 2013 GitHub annuncia di avere 3 milioni di utenti e più di 5 milioni di repository. Mentre scrivo queste righe, vi sono esattamente 34.872.546 utenti (quasi 35 milioni) verificati da me semplicemente usando le API fornite da loro (inviando una richiesta GET a questo indirizzo potrete vedere quanti utenti si sono iscritti dal momento che leggete questo paragrafo sino al vostro tentativo).

Perchè è importante GitHub? Anche se molti degli strumenti elencati nel paragrafo precedente sono anch’essi progetti open source, l'avvento di GitHub causa un'esplosione di nuovi framework JavaScript. Per avere un’idea possiamo utilizzare i dati forniti da un articolo del loro blog datato 2012.

Nel 2017 JavaScript è sempre il linguaggio più utilizzato secondo i dati presenti su GitHub (che sono un campione statistico molto rilevante in quanto quasi tutti gli sviluppatori privati e le compagnie tengono traccia del proprio codice utilizzando questo strumento.

Abbiamo effettuato questa panoramica su GitHub perché una caratteristica interessante dal suo avvento, non è tanto la quantità di librerie, quanto la loro diversità. GitHub riduce il costo di creazione di progetti basati su codice (qualsiasi esso sia) questo fa sì che possano nascere micro framework e strumenti altamente specializzati, focalizzati a risolvere un unico problema per soddisfare le crescenti esigenze di sviluppo web front-end in rapida evoluzione. Abbiamo visto in precedenza quanto tempo impiegavano le librerie prima di diffondersi, adesso questo problema non esiste più. Con GitHub, una volta sorto un problema nuovo, sviluppatori da ogni parte del mondo possono proporre alla comunità una soluzione al riguardo.

Ritornando al periodo storico preso in esame, verso la fine del primo decennio degli anni 2000, vi è la nascita di un enorme varietà di librerie JavaScript, fin troppe e non sempre tutte utili. Gli sviluppatori cercano di selezionare quelle più consone per creare la prossima generazione di applicazioni web, le SPA non sono ancora sviluppate come noi le conosciamo: abbiamo molte librerie e componenti ben strutturati su cui poter contare per lo sviluppo web di applicazioni client side, ma in questa epoca non hanno ancora imparato a lavorare assieme.

Benvenuti nella nuova era

Sembra strano affermarlo ma JavaScript esisteva come linguaggio lato server già dal lontano 1994 dove si poteva usare SSJS (Server Side JavaScript) con Netscape Enterprise Server. Utilizzato come linguaggio di scripting lato server al posto degli script CGI e di altre tecnologie per creare applicazioni web del tempo (fonte: capitolo 12 del libro “JavaScript - Tutto & oltre”, autori: Richard Wagner e R. Allen Wyke, editore: Apogeo) la cosa strana e buffa è che non prese piede in questo senso, almeno fino al 2009, anno di nascita di NodeJS.

NodeJS è un ambiente di run-time multipiattaforma ed open-source per l'esecuzione di codice JavaScript lato server. Di conseguenza, esso è diventato uno degli elementi fondanti del movimento JavaScript everywhere, che si spende per l’utilizzo di JS sia lato client che lato server, permettendo lo sviluppo di applicazioni web utilizzando un singolo linguaggio di programmazione, anziché basarsi su un linguaggio diverso per scrivere script server side.

NodeJS ha un'architettura event-driven (guidata da eventi) capace di input/output asincroni. Queste scelte progettuali mirano a ottimizzare il throughput e la scalabilità delle applicazioni web che necessitano di molte operazioni di questo tipo come programmi di comunicazione in tempo reale, chat e giochi browser. Ma il punto non è NodeJS in sé, che, per quanto importante sia, non è motivo di tale articolo, ma si deve cogliere una conseguenza fondamentale di tale espansione: la propaganda avuta grazie a NodeJS ha portato i programmatori ad affrontare questioni ingegneristiche simili a quelle avute in passato per altri linguaggi come il C al momento della creazione di Linux. Finalmente JavaScript non era più visto come un semplice linguaggio di scripting, ma si sentiva il bisogno di trovare delle soluzioni per renderlo più leggibile, robusto, modulare, flessibile ed efficiente. L’esecuzione in ambienti esterni di un linguaggio nato e cresciuto per essere eseguito nel browser richiede un’intera nuova classe di strumenti per l’organizzazione, la pacchettizzazione e la condivisione del codice. Questi strumenti esistevano da decenni per i classici linguaggi server, grazie a NodeJS sono nati e cresciuti tool per ovviare a tali problemi:

  1. Per l’organizzazione del codice, alcuni esempi: AMD, RequireJS, CommonJS. È pratica comune utilizzare molte librerie JavaScript, anche dipendenti tra loro, all’interno di uno stesso progetto. Condizione indispensabile per ottenere applicazioni e prodotti in linea con gli standard richiesti dal web moderno. Dato che JavaScript non è stato progettato con un metodo ufficiale per avere "namespace" o simili, come invece Java fa con i pacchetti, nel browser tutto verrebbe eseguito di default in una grande zuppa globale. Ci si è resi conto che se si voleva avere una visione a lungo termine di JavaScript, diventava necessario l’utilizzo di metodi che avrebbero dato la possibilità di gestire le dipendenze tra le varie librerie utilizzate, ottimizzare i tempi di caricamento delle pagine rendendo il codice pulito, modulare e facilmente comprensibile da tutti gli sviluppatori coinvolti nel progetto.

  2. Per la condivisione del codice, alcuni esempi: NPM, Bower. Tutti i linguaggi di scripting lato server possedevano già (e tutt’ora posseggono) repository in cui gli sviluppatori mettono a disposizione codice in pacchetti da poter essere scaricati da altri developer in caso di necessità. Per citare i più famosi: Pip per Python, RubyGems per Ruby, Maven ed Ivy per Java. JavaScript non aveva nulla di tutto ciò fino a quando NodeJS non fornì NPM, un’utility a linea di comando capace di gestire pacchetti, organizzare e condividere facilmente codice. Ciò che fa NPM lato server, Bower lo fa per le risorse che vengono eseguite nel browser. Vorrei sottolineare che, pur sembrando cose davvero scontate, stiamo invece parlando di contemporaneità storica, tenendo a mente che Bower è stato creato nel 2012 da Twitter.

  3. Per i vari task di automazione, alcuni esempi: Grunt, Gulp. Essi consentono di automatizzare i processi di build nei progetti complessi, estrapolano dipendenze, controllano la sintassi, effettuano la compressione del codice, eseguono le suite di test, svolgono il packaging e la distribuzione.

Finalmente, all'inizio del decennio, NodeJS ha portato un certo rigore ingegneristico al software dell'ecosistema JavaScript. Ora è riconosciuto come uno strumento legittimo e parallelamente alla sofisticazione avvenuta, siamo pronti a veder nascere le moderne SPA. 🤗