어플리케이션이 로드되는 즉시 모든 모듈이 필요한지에 대한 여부와 관계없이 로드된다.
이는 콜드 스타트가 중요한 서버리스 환경에서 실행되는 앱/작업자에게는 병목 현상이 될 수 있다.
Lazy-loadgin은 특정 서버리스 함수 호출에 필요한 모듈만 로드해 부트스트랩 시간을 줄이는 데 도움이 된다.
서버리스 기능이 "준비"가 되면, 다른 모듈을 비동기적으로 로드하여 후속 호출 부트스트랩을 더욱 가속화할 수 있다.(모듈 등록 연기)
다음과 같이 LazyModuleLoader
클래스를 직접 가져오는 경우도 있고, main.ts
에서 참조를 가져올 수도 있다
@Injectable()
export class CatsService {
constructor(private lazyModuleLoader: LazyModuleLoader) {}
}
// "app" represents a Nest application instance
const lazyModuleLoader = app.get(LazyModuleLoader);
위같이 하고, 다음과 같이 작성하면 모든 모듈을 로드할 수 있다.
const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
Lazy-loaded 모듈은 처음 메서드 호출 시 캐시된다.
그렇기에
LazyModule
을 후에 로드할 때는 더 빠르게 할 수 있다.
./lazy.module.js
는 일반 Nest 모듈을 내보내는 Typescript 파일이다.
load()
메서드는 모듈의 인스턴스를 반환한다.
예를 들어, 다음과 같은 LazyModule
이 있다고 가정해보자
@Module({
providers: [LazyService],
exports: [LazyService],
})
export class LazyModule {}
load()
메서드를 통해 위 모듈에 대한 참조를 얻는다.
그렇게 되면, 다음과 같이 LazyService
프로바이더에 대한 참조 또한 얻을 수 있을 것이다.
const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
const { LazyService } = await import('./lazy.service');
const lazyService = moduleRef.get(LazyService);
Webpack을 사용하는 경우에는
tsconfig.json
파일을 업데이트 해야한다.
compilerOptions.module
을esnext
로 설정하고 값으로node
를 사용해compilerOptions.moduleResolution
속성을 추가한다.{ "compilerOptions": { "module": "esnext", "moduleResolution": "node", ... } }
Nest의 컨트롤러나 GraphQL 어플리케이션의 리졸버는 routes/paths/topics의 집합을 나타내므로 LazyModuleLoader
클래스를 사용해 Lazy-loading할 수 없다.
worker/cron job/lambda & serverless function/webhook 이 입력 인수에 따라 다른 서비스를 트리거해야 하는 상황에서 Lazy-loading 모듈이 많이 쓰일 것이다.
반면, Lazy-loading 모듈은 모놀리식 어플리케이션에서는 사용할 일이 없을 것이다.