2012-02-03 13 views
13

Mi chiedevo se l'utilizzo di require() in node.js equivalesse al caricamento lazy? Ad esempio, se avessi una funzione che richiedeva uno specifico pacchetto node.js che non era necessario in nessun'altra parte del mio codice, è meglio usare require() all'interno di quella funzione per includere il pacchetto necessario solo quando viene chiamata quella funzione. .Caricamento lento in node.js

Non sono sicuro se ciò fornirà miglioramenti delle prestazioni data la mia mancanza di comprensione intorno all'architettura node.js? Presumo che userà meno memoria per connessione al mio server. Tuttavia aumenterà l'I/O sul disco quando deve leggere il pacchetto, o sarà uno solo per averlo in memoria?

Se questo è il caso in cui dovrei farlo, dovrei provare a scrivere i pacchetti node.js per il maggior numero di codice possibile?

risposta

21

require() è il caricamento su richiesta. Una volta che un modulo è stato caricato, non verrà ricaricato se viene eseguita nuovamente la chiamata require(). Inserendolo in una funzione anziché nel codice del modulo di primo livello, è possibile ritardarne il caricamento o potenzialmente evitarlo se non si invoca mai effettivamente tale funzione. Tuttavia, require() è sincrono e carica il modulo dal disco, quindi è consigliabile caricare tutti i moduli necessari all'avvio dell'applicazione prima che l'applicazione inizi a servire le richieste, garantendo quindi che solo l'IO asincrono avvenga mentre l'applicazione è operativa.

Il nodo è a thread singolo in modo che il footprint di memoria del caricamento di un modulo non sia per connessione, è per processo. Caricare un modulo è una tantum per averlo in memoria.

Basta attenersi alla convenzione qui e richiedere i moduli necessari al livello più alto della tua app prima di iniziare l'elaborazione delle richieste. Penso che questo sia un caso di, se devi chiedere se hai bisogno di scrivere il tuo codice in un modo insolito, non hai bisogno di scrivere il tuo codice in un modo insolito.

+0

Grazie Peter, questo ha reso tutto ha molto più senso. –

+6

Il caricamento anticipato non ha senso per gli strumenti CLI (tranne che per i test, in cui è possibile disabilitarlo temporaneamente). – sheerun

+1

@PeterLyons puoi spiegarmi la riga "Il nodo è a thread singolo, quindi l'impronta di memoria del caricamento di un modulo non è per connessione, è per processo, caricare un modulo è una tantum per farlo entrare in memoria". Capisco cos'è un singolo thread, intendi dire che qualunque sia il numero di connessioni al server, un particolare modulo verrà caricato solo una volta su tutta l'applicazione? – Deepak

2

Se si vuole moduli di carico pigri, la sua ora possibile con ES6 (Node v6)

Edit: Questo non funziona se è necessario per accedere alle proprietà di richiedere (come require.cache).

module.js

console.log('Module was loaded') 
exports.d=3 

main.js

var _require = require; 
var require = function (moduleName) { 
    var module; 
    return new Proxy(function() { 
     if (!module) { 
      module = _require(moduleName) 
     } 
     return module.apply(this, arguments) 
    }, { 
     get: function (target, name) { 
      if (!module) { 
       module = _require(moduleName) 
      } 
      return module[name]; 
     } 
    }) 
}; 

console.log('Before require'); 
var a = require('./module') 
console.log('After require'); 
console.log(a.d) 
console.log('After log module'); 

uscita

Before require 
After require 
Module was loaded 
3 
After log module 
Problemi correlati