在开发环境中,我的应用程序在启动阶段非常缓慢。我在各个地方设置了一些调试日志,以查看所花费的时间,发现我的main.ts
实际上用了将近{strong> 9分钟来获取我的app.module
进口的!
来源
import { performance } from 'perf_hooks';
const startTime = performance.now();
import { Log } from 'api/common/util/logger/log';
Log.log.info(`┌────────────────────────────────────────────────────────────┐`);
Log.log.info(`│ Starting: ${new Date().toISOString()} │`);
Log.log.info(`└────────────────────────────────────────────────────────────┘`);
// From here -------------------->
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import 'reflect-metadata';
import { existsSync, mkdirSync, writeFile } from 'fs';
import * as express from 'express';
import * as bodyParser from 'body-parser';
import * as helmet from 'helmet';
import * as morgan from 'morgan';
import * as morganBody from 'morgan-body';
// <------ to here, imports fly in as expected.
// Theese take a bit longer, but not enormously
import { Config } from './api/common/config';
import { HttpExceptionFilter } from './api/common/filters/http-exception.filter';
import { LogService } from 'api/common/util/logger/log.service';
// This one takes up the most time on startup (several minutes)
import { AppModule } from './api/app.module';
Log.log.debug(` * imports done in ${(performance.now() - startTime).toFixed(3)}ms`);
Log.log.debug(` * Memory: ${readMem()}`);
function readMem() {
const mem = process.memoryUsage();
const convert = { Kb: n => (n / 1024), Mb: n => convert.Kb(n) / 1024 };
const toHuman = (n, t) => `${convert[t](n).toFixed(2)}${t}`;
return `Used ${toHuman(mem.heapUsed, 'Mb')} of ${toHuman(mem.heapTotal, 'Mb')} - RSS: ${toHuman(mem.rss, 'Mb')}`;
}
输出
生产启动:
$ node dist/main.js
info: ┌──────────────────────────────────────────────────────────────────────────┐
info: │ Starting: 2019-01-29T13:06:13.751Z │
info: │ Memory: Used 6.54Mb of 11.70Mb - RSS: 25.33Mb │
info: │ Runtime: js │
info: └──────────────────────────────────────────────────────────────────────────┘
debug: * imports done in 6862.350ms
debug: * Memory: Used 87.99Mb of 113.76Mb - RSS: 133.58Mb
info: Nest application successfully started
info: ┌──────────────────────────────────────────────────────────────────────────┐
info: │ Memory: Used 93.71Mb of 122.52Mb - RSS: 144.20Mb │
info: │ Launch: 2019-01-29T13:06:25.377Z │
info: │ Time to start: 11991.049ms │
info: │ Bootstrap time: 5124.189ms │
info: └──────────────────────────────────────────────────────────────────────────┘
开发启动:
$ ts-node -r tsconfig-paths/register src/main.ts
info: ┌──────────────────────────────────────────────────────────────────────────┐
info: │ Starting: 2019-01-29T13:08:06.914Z │
info: │ Memory: Used 157.76Mb of 193.62Mb - RSS: 209.77Mb │
info: │ Runtime: ts │
info: └──────────────────────────────────────────────────────────────────────────┘
debug: * imports done in 471159.063ms
debug: * Memory: Used 297.45Mb of 385.35Mb - RSS: 408.90Mb
info: Nest application successfully started
info: ┌──────────────────────────────────────────────────────────────────────────┐
info: │ Memory: Used 216.64Mb of 383.35Mb - RSS: 409.11Mb │
info: │ Launch: 2019-01-29T13:16:05.521Z │
info: │ Time to start: 483228.325ms │
info: │ Bootstrap time: 12042.239ms │
info: └──────────────────────────────────────────────────────────────────────────┘
是的,我使用ts-node
开始,但这是NestJS建议进行开发和调试的。
我该如何优化启动,以使后端的每个微小更改都不需要10分钟的拖延?我已经无法专心,这无济于事。
我的模块太多了吗?如果结合使用会有所帮助吗?我具有大约15个DB实体模型,每个模型都包含在其自己的基于graphql的模块中,以提高可读性,但其中许多模型具有循环依赖性,可通过在模块导入中注入forwardRef()
来解决。这可能是个问题吗?
我尝试包括尽可能少的第三方库,以避免node_modules地狱。我在模块中导入的是我自己的代码或NestJS框架。当然,我不知道会加载多少隐式依赖关系,但是我随身携带的库的数量会影响启动性能吗?如果是这样,我该如何监视堆栈中包含的内容以及每个脚本在评估时消耗多少内存/ cpu?我可以以某种方式预编译其中的一部分以增加启动速度吗?
在生产环境中以编译的javascript运行时,我没有这个问题。
答案 0 :(得分:0)
尝试设置环境TS_NODE_TRANSPILE_ONLY=true
。
例如TS_NODE_TRANSPILE_ONLY=true ts-node -r tsconfig-paths/register src/main.ts
docs:https://github.com/TypeStrong/ts-node#cli-and-programmatic-options
这可以加快我的应用启动速度
答案 1 :(得分:0)
一种选择是使用tsc-watch而不是ts-node和nodemon。您可以在start:dev中设置启动命令,如下所示:
title
以我的经验,{
//this is assuming you're building to the dist folder
...
"start:dev": "tsc-watch --onSuccess \"node dist/main.js\" --onFailure \"echo
There was a problem with the build!\" -p tscfonig.json"
...
}
和注册路由时遇到了太多问题,加上加载时间使我丧命。使用ts-node
,我可以重新构建项目,仅重建已更改的文件。这样,您还可以在开发过程中测试tsc-watch
是否有效。
我还使用tsconfig-bootstrap命令导入我的自定义路由(在tsconfig中定义),并使用tsc
将其添加到start命令中。
希望这对您有所帮助!
答案 2 :(得分:0)
在全局和本地安装@nestjs/cli
的最新版本:
$ npm install -g @nestjs/cli
$ cd /some/project/root/folder
$ npm install -D @nestjs/cli
替换/确保您在package.json中定义了以下脚本
"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
运行
npm run start:dev
答案 3 :(得分:0)
一种合理的解决方案,并且可以解决问题的有效方法是,从应用程序模块中取消注释当前未使用的模块。
@Module({
imports: [
TypeOrmModule.forRoot(defaultOptions),
// Commented for faster reloads
// NotUsingModule1
// NotUsingModule2
UsingModule1
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
另外,如果要使用RDBMS,请确保未将登录设置为true,并且将dropSchema也设置为true。
export const defaultOptions = {
type: "postgres",
port: 5432,
username: "postgres",
password: "postgres",
database: "awesome db",
synchronize: true,
// logging: true,
// dropSchema: true,
entities: ['dist/**/*.entity.js'],
答案 4 :(得分:0)
添加这个以防其他人可能有同样的原因,我的问题是由于导入 grpc 客户端,两者都不够具体,包括哪些 proto(s) 以及在太多不同的地方。
我们的 protos 结构非常大,因此 grpc 加载器加载速度非常慢,导致 Nest 需要几分钟才能启动。
所以请确保在配置的 protoPath 中只使用您直接需要的服务。我认为 includeDirs 选项不重要,所以只是 protoPath。