2012-10-02 8 views
6

Domanda 1:Perché ho bisogno del caricamento del modulo JavaScript e qual è la differenza tra tutti questi caricatori?

Perché devo caricare asynchrously miei file JavaScript in una pagina web? Riesco a vedere le motivazioni per questo sul lato server, ma se conosco tutti i file che devo caricare nel client, perché non dovrei concatenare tutti i miei file sorgente in 1 file e caricarlo a caricamento pagina? Il primo caricamento della pagina iniziale è così importante che le operazioni future potrebbero essere rallentate a causa della latenza nel recupero di ogni file JS?

Domanda 2:

Supponendo che la risposta alla domanda 1 è che ho bisogno di caricare i file JS separatamente:

AMD carichi ogni JS file di asynchrously, carichi CommonJS sincrono. CJS è richiesto per il caricamento lato server (è così che funziona Node.js, se non sbaglio). AMD sembra essere la soluzione migliore per il cliente. Pertanto, l'unico motivo per utilizzare CJS nel client è quello di condividere il codice con il server.

C'è un modo per far sì che AMD e CJS funzionino bene, in modo che i file JS client possano essere caricati in modo asincrono ma avere ancora la sintassi CJS?

(Che cosa fa esattamente require.js fare? Non posso per la vita di me leggere tra le righe sul loro sito web.)

risposta

3

Non "bisogno" di caricare javascript file in modo asincrono o tramite qualche loader personalizzato. Ecco alcuni motivi per cui asincrono carico o personalizzato di carico potrebbe fornire un beneficio:

  • Quando il file JavaScript non è normalmente necessaria e si potrebbe desiderare di caricarlo su richiesta, piuttosto che tutto il tempo
  • Quando il file javascript non è necessario per la visualizzazione iniziale della pagina e si desidera massimizzare la velocità del primo display per la propria pagina
  • Quando si desidera controllare i tempi esattamente quando viene caricato il file javascript
  • Quando si decide, in base ad alcune condizioni , se caricare il file javascript o meno (ad esempio, se il caricamento da un CDN fallisce, si mi carico combattere da una posizione di backup)
  • Quando si desidera lo script di caricamento di procedere in parallelo con l'altro, piuttosto che uno dopo l'altro serializzato

Se non è necessario alcun di questi benefici o qualsiasi altra prestazione forniti da caricamento programmatico, quindi puoi semplicemente utilizzare i normali tag <script> e lasciarli caricare in modo sincrono.

+0

È ancora vero? –

+0

@JitendraVyas - Sì, è praticamente tutto vero. I browser hanno ora la '' defer' e attributi async' per il tag script (che potete leggere [qui] (http://stackoverflow.com/questions/10808109/script-tag-async-defer/10808243#10808243)), che vi darà un certo controllo sui tempi di appena un tag script semplice senza l'utilizzo di un caricatore, ma ci sono ancora dei casi per tutto quanto sopra che utilizzare un caricatore. – jfriend00

3

Parte del problema con il semplice concatenamento del file non è il tempo impiegato per il download, è il tempo impiegato per la compilazione di ogni pagina.

Se hai un file di 20.000 linea, e hai solo bisogno di 600 di queste linee per ottenere tutto installato e funzionante (supponendo che tutto è scritto per essere modulare e asincrona, utilizzando qualsiasi modello a tutti per la gestione delle risorse) , quindi risparmierai quello che potrebbe essere mezzo secondo o più, se servi il programma principale ed estendi al bisogno (o su un timer ritardato, servendo grossi pezzi di funzionalità che sono strettamente correlati l'un l'altro).

Il tempo di scaricamento complessivo è più alto.
Il numero complessivo di connessioni HTTP utilizzate è più alto.
Ma il tempo necessario per rendere la pagina visibile all'utente è inferiore.
Il tempo necessario per aggiungere funzionalità di base alla pagina è inferiore.
funzionalità Poi extra può essere trasmesso in streaming in, sia dopo il carico e l'inizializzazione, o just-in-time, as-richiesto dall'utente, e in entrambi i casi, fino a quando il codice che hai trasmesso in streaming in è focalizzata sul fare una cosa, e non sta richiedendo una mezza dozzina di altre dipendenze, il tempo tra la richiesta e l'aggiunta della funzionalità sarà minimo.

RequireJS utilizza un sistema di promessa, in pratica.

Consente di dichiarare le dipendenze in primo piano e di consegnare il codice (come callback) da implementare, dopo che tutte le sue dipendenze sono state gestite.
Se tali dipendenze hanno dipendenze, quindi esse non verranno inizializzate fino a quando non vengono caricate le loro dipendenze.
Se si desidera caricarlo e l'ordine non è importante, non è necessario fornire dipendenze.

La morale generale è che, se si dispone di un sistema in cui tutti i file sono piccoli, il peso complessivo di JS sulla pagina è molto piccolo, bastano poche centinaia di righe per eseguire tutto ciò che si desidera sul pagina ... ... in più, sai dove sono tutte le tue dipendenze, hai un sistema sul server per assicurarti che siano nell'ordine giusto, eccetera (in più hai una buona documentazione, o te ') sei l'unico che tocca questo codice e vivi al suo interno, giorno dopo giorno ... ... quindi non c'è niente di sbagliato nel fare ciò che stai facendo.

Potrebbe non notare alcuna differenza, se il tempo di compilazione è superato dal numero di richieste HTTP effettuate. Ma per le applicazioni complessive che sono lunghe decine (o centinaia) di migliaia di righe, dove è necessaria solo una frazione di quella funzionalità su una singola pagina, ci possono essere grandi risparmi in termini di tempo percepito tra il caricamento della pagina e quando l'app è "pronta" per l'interazione di base da parte dell'utente.

3

Se si desidera caricare l'intero sorgente JavaScript per ogni pagina, certo, compilarlo in un unico file. Se si carica un codice diverso in base a quali azioni l'utente esegue o in base a quale pagina è stata caricata, utilizzare i moduli caricati AMD. L'altra alternativa sarebbe quella di elencare una serie di tag di script, che ovviamente verrebbero caricati solo uno alla volta e potrebbero richiedere del tempo.

AMD non è una libreria specifica, è in realtà uno standard per il caricamento di moduli javascript che la maggior parte dei caricatori che hai citato utilizzano. Ciò significa che tutti usano una sintassi simile per la definizione e il caricamento dei moduli. Stanno considerando di fare parte di AMD delle specifiche di script ECMA. L'utilità è che puoi anche definire le dipendenze, quindi se il tuo codice richiede l'esecuzione di jQuery, puoi elencarlo come dipendenza, e verrà caricato nel tuo spazio dei nomi dei moduli.

define([ 'jquery' ], function ($) { 
    // use jquery in here without clouding up the global namespace 

    return {}; // return your module for use in a different module or whatever 
}; 

In questo esempio, il codice nel modulo definito non verrà eseguito finché il modulo jquery è stato scaricato. Inietterà quindi il modulo jQuery direttamente nel modulo appena definito come argomento $.

È ora possibile mantenere il vostro codice organizzata ordinatamente in file che contengono i moduli. Nessuno dei tuoi moduli oscurerà lo spazio dei nomi globale. Tutte le tue dipendenze saranno sicuramente caricate prima dell'esecuzione del modulo (nessun bug di condizione di competizione per pezzi di codice dipendenti).

Un altro vantaggio è che è possibile impostare il proprio caricatore per utilizzare percorsi diversi per lo stesso modulo, in modo da poter definire il percorso per il modulo jquery come "https://ajax.googleapis.com/ajax/libs/jquery /1.8.2/jquery.min.js 'in un punto del codice anche se può essere utilizzato in quasi tutti i moduli. Ora, quando ho bisogno di aggiornare la mia versione jQuery a 1.8.3, posso semplicemente modificare il percorso in un punto nel mio codice, e sarà utilizzare questo percorso per ogni modulo che utilizza jquery come dipendenza. Questo può anche essere utile per cambiare facilmente durante il test quando si utilizzano gli stub dei moduli o le versioni di debug di alcuni moduli.

Ora, questo non è necessariamente necessari per i progetti piccoli. Più grande sarà il tuo progetto, più sensato iniziare questo tipo di caricamento.

Problemi correlati