Nodejs のパフォーマンス最適化に関する 10 のヒント

高洛峰
リリース: 2017-02-04 13:05:34
オリジナル
1644 人が閲覧しました

Node.js を使用するときに従う 10 のパフォーマンス ルールを次に示します。

1. 同期コードの使用を避ける

設計上、Node.js はシングルスレッドです。単一のスレッドが多数の同時リクエストを処理できるようにするには、スレッドがブロック操作、同期操作、または長時間実行操作を待機するようにすることはできません。 Node.js の特徴は、非同期実装を実現するために上から下まで設計および実装されることです。これは、イベントベースのプログラムに最適です。

残念ながら、同期/ブロック呼び出しが依然として発生する可能性があります。たとえば、writeFile や writeFileSync など、多くのファイル システム操作には同期バージョンと非同期バージョンの両方があります。コードを使用して同期方法を制御した場合でも、呼び出しをブロックする外部関数ライブラリを誤って使用してしまう可能性があります。これを行うと、パフォーマンスへの影響は大きくなります。

// Good: write files asynchronously
fs.writeFile('message.txt', 'Hello Node', function (err) {
 console.log("It's saved and the server remains responsive!");
});
  
// BAD: write files synchronously
fs.writeFileSync('message.txt', 'Hello Node');
console.log("It's saved, but you just blocked ALL requests!");
ログイン後にコピー

初期化ログの実装には、内容をディスクに書き込むための同期呼び出しが誤って含まれていました。パフォーマンス テストを行わない場合、この問題は無視されがちです。開発者向けボックスの Node.js インスタンスに対してテストすると、この同期呼び出しによりパフォーマンスが 1 秒あたり数千リクエストからわずか数十リクエストに低下します。

2. ソケット プールをオフにする

Node.js の http クライアントは自動的にソケット プールを使用します。デフォルトでは、各ホストは 5 つのソケットのみに制限されます。ソケットの再利用によりリソースの増加は抑制される可能性がありますが、同じホストからのデータに対する多数の同時リクエストを処理する必要がある場合、一連のボトルネックが発生する可能性があります。この場合、maxSockets の値を増やすか、ソケット プールを閉じることをお勧めします:

// Disable socket pooling
  
var http = require('http');
var options = {.....};
options.agent = false;
var req = http.request(options)
ログイン後にコピー

3. 静的リソースには Node.js を使用しないでください

CSS や画像などの静的リソースには、標準の WebServer を使用してください。代わりに Node.js を使用します。たとえば、LinkedIn モバイルは nginx を使用します。また、静的資産を世界中のサーバーにコピーできるコンテンツ配信ネットワーク (CDN) も利用しています。これには 2 つの利点があります: (1) Node.js サーバーの負荷を軽減できます (2) CDN により、ユーザーに近いサーバーで静的コンテンツを配信できるため、待ち時間を短縮できます。

4. クライアント側でのレンダリング

サーバー レンダリングとクライアント レンダリングの違いを簡単に比較してみましょう。サーバー側でのレンダリングにnode.jsを使用する場合、リクエストごとに次のようなHTMLページを送り返します:

<!-- An example of a simple webpage rendered entirely server side -->
  
<!DOCTYPE html>
<html>
 <head>
  <title>LinkedIn Mobile</title>
 </head>
 <body>
  <div class="header">
   <img src="http://mobile-cdn.linkedin.com/images/linkedin.png" alt="LinkedIn"/>
  </div>
  <div class="body">
   Hello John!
  </div>
 </body>
</html>
ログイン後にコピー

このページのコンテンツは、ユーザー名を除いてすべて静的コンテンツであることに注意してください:各リクエスト コンテンツは各ユーザーおよびページのリロードごとに同じです。したがって、Node.js がページに必要な動的コンテンツのみを JSON 形式で返すようにする方が効率的です。

{"name": "John"}
ページの残りの部分 (すべて静的 HTML マークアップ) は、JavaScript テンプレート (underscore.js テンプレートなど) に配置できます。

<!-- An example of a JavaScript template that can be rendered client side -->
  
<!DOCTYPE html>
<html>
 <head>
  <title>LinkedIn Mobile</title>
 </head>
 <body>
  <div class="header">
   <img src="http://mobile-cdn.linkedin.com/images/linkedin.png" alt="LinkedIn"/>
  </div>
  <div class="body">
   Hello <%= name %>!
  </div>
 </body>
</html>
ログイン後にコピー

パフォーマンスの向上は次の場所から得られます。 3 つのポイントで説明したように、静的 JavaScript テンプレートは、Web サーバー (nginx など) を通じてサーバー側で提供することも、より優れた CDN を使用して実装することもできます。さらに、JavaScript テンプレートはブラウザーにキャッシュすることも、ローカルに保存することもできます。最初のページがすべて読み込まれた後、クライアントに送信する必要があるのは JSON だけです。これが最も効果的です。この方法により、CPU、IO、Node.js の負荷を大幅に軽減できます。

5. gzip を使用する

Nodejs のパフォーマンス最適化に関する 10 のヒント

多くのサーバーとクライアントは、リクエストとレスポンスを圧縮するために gzip をサポートしています。クライアントに応答する場合でも、リモート サーバーにリクエストを送信する場合でも、最大限に活用してください。

6. 並列化

Nodejs のパフォーマンス最適化に関する 10 のヒント

リモート サービスへのリクエストの送信、DB 呼び出し、ファイル システム アクセスなど、すべてのブロッキング操作を並列化してみてください。これにより、すべてのブロック操作の待機時間ではなく、最も遅いブロック操作の待機時間が短縮されます。コールバックとエラー処理をクリーンに保つために、Step を使用してフローを制御します。

7.セッションの自由化

LinkedIn Mobile は、Express フレームワークを使用してリクエスト/レスポンス サイクルを管理します。多くの Express 例には、次の構成が含まれています:

app.use(express.session({ Secret: "keyboard cat" }));
デフォルトでは、セッション データはメモリに保存されるため、サーバーのオーバーヘッドに膨大なオーバーヘッドが追加されます。特にユーザー数が増えるにつれて。 MongoDB や Redis などの外部セッション ストアを使用できますが、リクエストごとにセッション データを取得するためのリモート呼び出しのオーバーヘッドが発生します。可能であれば、すべてのステートレス データをサーバー側に保存することが最善の選択肢です。上記の高速構成を含めずにセッションを解放すると、パフォーマンスが向上します。

8. バイナリ モジュールを使用する

可能であれば、JavaScript モジュールをバイナリ モジュールに置き換えます。たとえば、JavaScript で書かれた SHA モジュールからコンパイル済みバージョンの Node.js に切り替えると、パフォーマンスが大幅に向上します:

// Use built in or binary modules
var crypto = require(&#39;crypto&#39;);
var hash = crypto.createHmac("sha1",key).update(signatureBase).digest("base64");
ログイン後にコピー

9 クライアント ライブラリを標準の V8 JavaScript に置き換えます

多くの JavaScript ライブラリは、JavaScript 環境が異なるため、Web ブラウザーで使用するために作成されています。たとえば、一部のブラウザーは forEach、map、reduce などの関数をサポートしていますが、一部のブラウザーはサポートしていません。そのため、クライアント ライブラリはブラウザの違いを克服するために多くの非効率なコードを使用することがよくあります。一方、Node.js では、どの JavaScript メソッドが有効であるかを正確に把握できます。V8 JavaScript エンジンは、ECMA-262 5th Edition で規定されている ECMAScript の Node.js 実装をサポートします。クライアント ライブラリを標準の V8 JavaScript 関数に置き換えるだけで、パフォーマンスが大幅に向上します。

10. コードを小さく軽く保つ

モバイルデバイスを使用するとアクセスが遅くなり、レイテンシが高くなるため、コードを小さく軽く保つ必要があります。サーバーコードについても同じ哲学を維持してください。時々、自分の決定を振り返り、「このモジュールは本当に必要なのか?」、「なぜこのフレームワークを使用するのか、オーバーヘッドはそれだけの価値があるのか​​?」、「もっと簡単な方法で実現できないか?」などの質問を自問してください。 ?」通常、コードが小さくて軽いほど、効率が高く、高速になります。

お試しください

私たちはモバイルアプリを高速化するために懸命に取り組んでいます。 iPhone アプリ、Android アプリ、HTML5 モバイル バージョンで試してみて、その結果をお知らせください。

nodejs のパフォーマンス最適化の 10 のヒントに関連するその他の記事については、PHP 中国語 Web サイトに注目してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート