Cloud Run 用に Node.js アプリケーションを最適化する

このガイドでは、Node.js ランタイムで実行され、JavaScript または TypeScript で記述された Cloud Run サービスの最適化について説明します。このページの情報は、Node.js にも適用される全般的な開発のヒントを補完するものです。

起動時間を最適化する

起動時間を最適化することで、レイテンシを短縮し、応答性を向上させ、費用を効果的に最適化できます。このセクションでは、起動時間を最適化するさまざまな方法について説明します。

npm ではなく node を使用してアプリを起動する

npm を使用するとレイテンシが増加するため、npm start ではなく node index.js を使用してアプリケーションを直接起動します。

node index.js でアプリケーションを開始するには、次のいずれかの方法を使用します。

  • Dockerfile で CMD node index.js を使用します。次に例を示します。

    CMD node index.js
    
  • node index.js をエントリ ポイントとして設定します。Google Cloud CLI を使用して次のコマンドを実行します。

    gcloud run deploy SERVICE --command "node index.js"
    

    エントリポイントの構成の詳細とオプションについては、サービスのコンテナを構成するをご覧ください。

Dockerfile なしでソースデプロイを使用する場合、Cloud Run が最適化を行います。

コードをバンドルする

バンドルは、JavaScript ソースファイルのレイアウトを最適化して読み込み時間を短縮するビルドツールです。一般的なバンドルの最適化には、ツリー シェイキング、圧縮、小さなファイルの統合などがあります。バンドラを使用すると、バンドルの合計サイズを大幅に削減し、ファイル読み取りリクエストの数を減らすことができます。一般的な JavaScript バンドラには、esbuildwebpackrollup があります。

依存関係の遅延読み込み

起動時に、Cloud Run はコードがリモート ロケーションから読み込む各ファイルをストリーミングします。ローカル ファイル システムと比較して、リモート ロケーションを使用すると、ファイルの読み取りごとにレイテンシが増加します。Node.js パッケージは、間接的な依存関係を持つ多くのファイルを使用する場合があります。起動時にすべての依存関係をインポートするのではなく、サーバーの起動に必要な依存関係のみを読み込み、他の依存関係は動的インポートで遅延読み込みすることをおすすめします。

たとえば、モジュールの上部で import { Storage } from '@google-cloud/storage' などのインポートを使用するのではなく、インポートされたオブジェクトが必要な場合は関数で import() を使用します。次に例を示します。

const { Storage } = await import('@google-cloud/storage');

起動時に読み込まれるモジュールと、各モジュールがマシンに読み込まれるのにかかる時間を特定するには、次のコマンドを実行します。

node --trace-event-categories node.module_timer --trace-event-file-pattern 'trace-events.log' index.js

タイムアウトを構成する

Node.js の組み込み HTTP サーバーのデフォルトのタイムアウトは 2 分です。Cloud Run サービスのリクエスト タイムアウトが長い場合は、server.setTimeout(msecs) を使用してタイムアウトを変更します。また、Express など、Node.js サーバーで構築されたフレームワークのタイムアウトも変更する必要があります。Node.js で無制限のタイムアウトを実現し、Cloud Run の組み込みタイムアウトを使用するには、server.setTimeout(0) を使用します。