開発環境の私のアプリケーションは、起動段階で迷惑なほど遅いです。さまざまな場所にデバッグログを設定して、何が非常に時間がかかっているかを確認しましたが、私の_main.ts
_は実際にはほぼ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分間の先延ばしが不要になるように、スタートアップを最適化するにはどうすればよいですか?そのまま集中力に困っていますが、仕方がありません。
モジュールが多すぎませんか?いくつか組み合わせると役に立ちますか?読みやすくするために、それぞれが独自のgraphqlベースのモジュールに含まれている約15のDBエンティティモデルがありますが、それらの多くは、モジュールのインポートでforwardRef()
インジェクションによって解決される循環依存関係を持っています。これはおそらく問題ですか?
Node_modulesの地獄を避けるために、サードパーティのライブラリをできるだけ少なくするようにしています。モジュールにインポートするのは、自分のコードまたはNestJSフレームワークのものです。もちろん、ロードされる暗黙の依存関係の数はわかりませんが、ドラッグしているライブラリの量が起動パフォーマンスに影響を与える可能性はありますか?もしそうなら、スタックに何が入るのか、評価時に各スクリプトがどれだけのメモリ/ CPUを消費するのかをどのように監視できますか?そして、私はどういうわけかこれのいくつかをプリコンパイルしてスタートアップを増やすことができますか?
本番環境でコンパイル済みのJavaScriptとして実行している場合、この問題は発生しません。
1つのオプションは、ts-nodeとnodemonの代わりに tsc-watch を使用することです。 start:devでstartコマンドを次のように設定できます。
{
//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
を使用すると、プロジェクトの新しいビルドを取得し、変更されたファイルのみを再ビルドします。このようにして、開発中にtsc
が機能することもテストします。
また、tsconfig-bootstrapコマンドを使用してカスタムルート(tsconfigで定義)をインポートし、それをnode -r path/to/my/script.js dist/main.js
を使用してstartコマンドに追加します。
これが少しお役に立てば幸いです。
@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