2012-02-03 18 views
13

Me preguntaba si el uso de require() en node.js era equivalente a la carga diferida?Carga lenta en node.js

Por ejemplo, si tenía una función que requería un paquete node.js específico que no era necesario en ningún otro lugar de mi código, lo mejor es usar require() dentro de esa función para incluir el paquete necesario solo cuando se llame a esa función .

¿No estoy seguro de si esto proporcionará alguna mejora en el rendimiento dada mi falta de comprensión en torno a la arquitectura node.js? Supongo que usará menos memoria por conexión a mi servidor. Sin embargo, ¿aumentará la E/S en el disco cuando tenga que leer el paquete, o será una sola para obtenerlo en la memoria?

Si este es el caso, ¿qué tan lejos debería tomar esto, debería estar intentando escribir paquetes node.js para la mayor cantidad de código que pueda?

Respuesta

21

require() carga bajo demanda. Una vez que se haya cargado un módulo, no se volverá a cargar si la llamada a require() se ejecuta nuevamente. Al ponerlo dentro de una función en lugar de su código de módulo de nivel superior, puede retrasar su carga o evitarla si nunca invoca esa función. Sin embargo, require() es síncrono y carga el módulo desde el disco, de modo que lo mejor es cargar los módulos que necesita al inicio de la aplicación antes de que la aplicación comience a atender solicitudes, lo que garantiza que solo se produzca IO asíncrona mientras la aplicación esté operativa.

El nodo tiene una sola hebra, por lo que la huella de memoria de cargar un módulo no es por conexión, es por proceso. Cargar un módulo es una opción única para tenerlo en la memoria.

Simplemente siga las convenciones aquí y solicite los módulos que necesita en el ámbito de nivel superior de su aplicación antes de comenzar a procesar las solicitudes. Creo que este es un caso de, si tiene que preguntar si necesita escribir su código de una manera inusual, no necesita escribir su código de una manera inusual.

+0

Gracias Peter, esto hizo que todo tenga mucho más sentido. –

+6

La carga anticipada no tiene sentido para las herramientas CLI (excepto para las pruebas, donde podría desactivarlo temporalmente). – sheerun

+1

@PeterLyons puede explicarme la línea "El nodo tiene un solo hilo, por lo que la huella de memoria de cargar un módulo no es por conexión, es por proceso. Cargar un módulo es una tarea única para tenerlo en la memoria". Entiendo lo que es un hilo único, ¿quiere decir que sea cual sea el número de conexiones al servidor, un módulo en particular se cargará solo una vez en toda la aplicación? – Deepak

2

Si desea módulos de carga perezosa, es ahora posible con ES6 (v6 Nodo)

Editar: Esto no funcionará si necesita acceder a las propiedades de requerir (como 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'); 

salida

Before require 
After require 
Module was loaded 
3 
After log module 
Cuestiones relacionadas