Javascript : caricare script dinamicamente e dipendenze

Come si sa il modo più sempice e classico per caricare file javscript in una pagina è l’uso del tag <script> messo nell’ head della pagina HTML. Ad esempio, se vogliamo caricare il file javascript myfunc.js scriveremo qualcosa del genere:

image

Alcune delle considerazioni che possiamo fare sono:

  • i file vengono caricati in serie (anche se questo non è sempre vero per tutti i browser) e questo può portare ad un rallentamento del caricamento iniziale della pagina, a maggior ragione in presenza di numerosi file e soprattutto la prima volta che un visitatore arriva su un nostro sito e i file .js non sono nella cache del suo computer.
  • inoltre se carichiamo un file molto grosso, con delle funzioni che non vengono usate fino  a quando l’utente non fa qualcosa sulla pagina, il caricamento della pagina rimane in attesa inutilmente. Se carichiamo una complicatissima funzione somma (o una funzione per la verifica di acquisto, ad esempio) ma il nostro visitatore non premerà il pulsante somma o acquisto, abbiamo fatto un’operazione di carimento in questo caso inutile e magari l’utente ha l’impressione che il sito sia lento perchè la pagina non viene caricata subito.

Se siamo giunti a queste considerazioni, o ci troviamo nel caso di volere ottimizzare la pagina, probabilmente ci si presenta la possibilità di aggiungere dinamicamente i file javascript al DOM della pagina stessa. Il DOM è il Document Object Model ed è sostanzialmente una rappresentazione ad albero di tutto quello che compone la nostra pagina HTML. In un punto a piacere nel body della pagina potremmo volere modificare il DOM nel modo seguente: il codice dovrebbe funzionare su tutti i browser più recenti:

image

A questo punto il file javascript verrà aggiunto alla pagina.

Il vantaggio più evidente di questa tecnica è che possiamo aggiungere file javascript in un secondo momento rispetto al primo caricamento della pagina e magari on-demand, cioè solo quando ne abbiamo bisogno ad esempio quando l’utente preme un pulsante.

Ok, ma quali possibili problemi possiamo incontrare?

  • il file javscript potrebbe essere già presente e magari già caricato nel DOM. Supponiamo di voler aggiungere jquery alla pagina, se la pagina non l’abbiamo fatta noi o magari andiamo ad inserire del codice in una pagina già fatta, ad esempio in un blog, il file potrebbe essere già presente. JQuery è una libreria molto usata ed è molto probabile che sia già stata usata da qualche parte.
  • Quando andiamo ad usare le funzioni della libreria dobbiamo verificare che questa sia disponibile nel momento in cui il nostro codice javascript la usa. Questa volta il caricamento avviene in modo asincrono e quindi il codice potrebbe richiamare una funzione di una libreria non ancora caricata.

Guardiamo il codice seguente dove carico jquery usando la tecnica vista e poi faccio una semplice chiamata usando l’oggetto Jquery per andare ad impostare un alert su un tag ancora:

image

Se lancio l’applicazione ottengo un errore: perchè l’oggetto JQuery, cioè $, non è ancora definito quando lo devo usare, lo vedete bene nella developer toolbar di Internet Explorer 8:

image

Ironia della sorte l’oggetto $ è proprio quello che jQuery mi mette a disposizione per verificare che il DOM della pagina è pronto. Il motivo è proprio che l’oggetto JQuery, cioè il simbolo $, non è definito nel momento in cui eseguiamo il nostro codice Javascript che vuole usare la suddetta libreria. Per preveniere questa situazione alcune tecniche di programmazione Javascript prevedono d’ implementare una sorta di timer in attesa del caricamento effettivo della libreria: una tecnica che funziona e che non è neanche così inefficente come potrebbe sembrare.

  • un altro problema che possiamo incontrare è la gestione delle dipendenze: se vogliamo caricare dinamicamente in modo asincrono ma ci sono delle dipendenze tra i file javascript, la situazione si complica ulteriormente: ad esempio se vogliamo usare la libreria jQueryUI, questa dipende da jquery. Quindi in questo caso dovrei essere sicuro di caricare prima jquery, alla fine del caricamento e solo alla fine, caricare jquery.UI e quando le librerie di jQueryUI sono disponibili scrivere il mio codice.

Per risolvere queste problematiche ed avere numerosi altri vantaggi possiamo usare il Microsoft Ajax Script Loader, un componente della Microsoft Ajax Library,ed in particolare il modulo che implementa un loader per file javascript e la gestione delle dipendenze: Start.js.

Il Microsoft Ajax Script Loader

Il modo più rapido per imparare ad usare le MS Ajax Library è partire da questo link al sito. Nel seguito mi focalizzerò primariamente sul loader, le caratteristiche di questo loader sono:

  • contenuto in un unico file Start.js che può essere scaricato dalla CDN Microsoft, o localmente al vostro progetto. L’uso di una CDN consente di migliorare i tempi di download avendo una cache distribuita sui server Microsoft in modo geografico.
  • Riduce i tempi di download iniziali di un’applicazione, differndo il downlaod del javascript in seguito.
  • contiene riferimenti ad un serie di file javascript come Jquery o le MS Ajax library che vengono scaricate da una CDN, ma se ne possono aggiungere di propri e anche per questi definire delle dipendenze.
  • gestiste le dipendenze tra file javascript in modo che vengano caricati nell’ordine opportuno per il loro buon funzionamento.
  • consente di combinare tra loro file javscript in un unico file, prima del downlaod, così da fare un unico downlaod di un file invece di n piccoli download, che scatenerebbero più richieste http sulla rete.
  • esegue il caricamento di file javascript on-demand, quando effettivamente richiesto.

Vediamo un primo esempio d’uso:

Caricamento dei file js necessari

image

Inizialmente ho caricato il file Start.js, il nostro loader appunto, direttamente dalla CDN Microsoft, non ho dovuto quindi aggiungere nessun file .js al mio progetto.

Usando ora l’istruzione Sys.require, Visual Studio ci mette a disposizione l’intellicese anche per queste istruzioni Javascript, possiamo specificare quali sono i file javascript necessari. Come vi dicevo il loader ha già una serie di file preimpostati, tra questi c’è anche jquery e quindi potete scrivere Sys.scripts.jQuery.

La lista dei file disponibili out-of-the box  (al momento) è:

image

I file vengono presi dalla CDN microsoft. Nella CDN trovate anche jquery 1.4.1 e potete utilizzare quest’utima versione con la tecnica vista nel seguito, in cui andremo a indicare file custom da caricare.

Inoltre notate che all’istruzione Sys.require viene passata la funzione funDOM che verrà eseguita al caricamento completato e quando sarà disponibile l’oggetto jQuery. In questo modo quindi:

  • abbiamo caricato il file jQuery dalla CDN in asincrono (rispetto al caricamento iniziale della pagina).
  • siamo certi che il codice eseguito dalla funzione funDOM potrà contare sul fatto che gli oggetti nel file javascript da cui dipende sono disponibili.

Caricamento dei file js custom e in dipendenza

L’ Ajax Script Loader ci consente anche di  caricare file custom, cioè non quelli presenti sulla CDN, come ad esempio jqueriUI. Quest’ultimo in dipendenza da JQuery, per fare questo dobbiamo prima istruire il loder sulle dipendeze, come nel codice seguente:

image

Il codice usa il metodo .defineScript per definire il file custom, nelle due versioni release e debug. La versione scelta è definita da una costane nel loader, verrà presa quella di release se il file è Start.js, quella di debug se il file è Start.debug.js.

Vedete inoltre che il file jquery.ui dipende (dependencies) dal file jQuery, ma la lista potrebbe essere estesa e il caricamento del file sarà considerato completato (isLoaded)quando le variabile windows.jQuery e jQuery.ui saranno definite.

Grazie a questo codice possiamo scrivere:

image

Questa volta semplicemente impostiamo come required lo script JQueryUI, che a sua volta dipende da JQuery. La nostra funcDOM funzionerà correttamente, il datepicker ad esempio è un plugin di jquery. Nella scherma seguente vedete un’esempio in esecuzione all’interno del browser Opera 10:

image

Conclusione

In questo post abbiamo visto come il Microsoft Ajax Loader, consenta di risolvere alcuni dei problemi più fastidiosi che si hanno quando si lavora con il javascript come: caricamento on-demand di file js, gestione delle dipendenze tra file js, verifica del caricamento dei file js prima dell’esecuzione di file javascript nella pagina. Vi posso consigliare anche di leggere questi how-to su: HOW TO Detect DOM Ready, in cui vedere come usare le funzioni  .domReady e .pageLoad; ed in generale trovate molte informazioni sulle Microsoft Ajax Library a questo link.

Spero che il post vi sia piaciuto.

Download

Potete scaricare il codice dell’esempio da qui.