2012-02-03 14 views
13

Zastanawiam się, czy użycie require() w pliku node.js było równoważne z leniwym ładowaniem?Leniwe ładowanie w pliku node.js

Na przykład, gdy miałem funkcję, która wymagała określonego pakietu node.js, który nie był potrzebny nigdzie indziej w moim kodzie, najlepiej użyć require() wewnątrz tej funkcji, aby dołączyć potrzebny pakiet tylko wtedy, gdy ta funkcja jest wywoływana .

Nie jestem również pewien, czy zapewni to poprawę wydajności, biorąc pod uwagę mój brak zrozumienia wokół architektury node.js? Zakładam, że zużyje mniej pamięci na połączenie z moim serwerem. Czy jednak zwiększy liczbę operacji wejścia/wyjścia na dysku, gdy będzie musiał odczytać pakiet, czy może to być jednorazowe, aby uzyskać je w pamięci?

Jeśli tak, to jak daleko powinienem to zrobić, czy powinienem próbować napisać pakiety node.js na tyle ile mogę?

Odpowiedz

21

require() to ładowanie na żądanie. Po załadowaniu modułu nie zostanie ponownie załadowany, jeśli wywołanie require() zostanie uruchomione ponownie. Wstawiając go do funkcji zamiast kodu modułu najwyższego poziomu, możesz opóźnić jego ładowanie lub potencjalnie go ominąć, jeśli nigdy nie wywołasz tej funkcji. Jednak require() jest synchroniczny i ładuje moduł z dysku, więc najlepszą praktyką jest załadowanie wszystkich modułów, których potrzebujesz podczas startu aplikacji, zanim aplikacja zacznie obsługiwać żądania, co zapewnia, że ​​tylko asynchroniczna operacja IO ma miejsce, gdy aplikacja działa.

Węzeł jest jednowątkowy, więc ślad pamięci związany z ładowaniem modułu nie jest zależny od połączenia, tylko proces. Ładowanie modułu jest jednorazowe, aby wprowadzić go do pamięci.

Koniecznie przestrzegaj konwencji i wymagaj modułów, których potrzebujesz, w górnym zakresie aplikacji, zanim zaczniesz przetwarzać żądania. Myślę, że jest to przypadek, jeśli musisz zapytać, czy musisz napisać swój kod w niecodzienny sposób, nie musisz pisać kodu w niecodzienny sposób.

+0

Dzięki Peter, to sprawiło, że wszystko zrobić dużo więcej sensu. –

+6

Wczesne ładowanie nie ma sensu w przypadku narzędzi CLI (z wyjątkiem testów, w których można je tymczasowo wyłączyć). – sheerun

+1

@PeterLyons możesz mi wytłumaczyć wiersz "Węzeł jest jednokrotnym gwintem, więc ślad pamięci przy ładowaniu modułu nie jest zależny od połączenia, jest to proces w trakcie procesu. Ładowanie modułu jest jednorazowe, aby go załadować do pamięci". Rozumiem, co to jest pojedynczy wątek, czy chcesz powiedzieć, że niezależnie od liczby połączeń z serwerem, dany moduł zostanie załadowany tylko raz w całej aplikacji? – Deepak

2

Jeśli chcesz leniwych modułów obciążenia, jej teraz możliwe ES6 (v6 Node)

Edit: To nie będzie działać, jeśli chcesz uzyskać dostęp do właściwości wymagają od (jak 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'); 

wyjściowe

Before require 
After require 
Module was loaded 
3 
After log module