node.jsを使用するときに従う10のパフォーマンスルールを次に示します。
1.同期コードの使用は避けてください
設計に関しては、node.jsはシングルスレッドです。単一のスレッドが多くの同時リクエストを処理できるようにするには、スレッドがブロック、同期、または長期にわたる操作を待たせることはできません。 node.jsの特徴的な機能は、非同期を実現するために上から下に設計および実装されていることです。これにより、イベントタイプのプログラムに非常に適しています。
残念ながら、同期/ブロッキングコールが発生する可能性がまだあります。たとえば、多くのファイルシステム操作には、writefileやwritefilesyncなど、同期バージョンと非同期バージョンの両方があります。コードを使用して同期メソッドを制御している場合でも、コードを不注意にブロックする外部関数ライブラリを使用することは依然として可能です。これを行うと、パフォーマンスへの影響は膨大です。
// good:asynchronallyfs.writefile( 'message.txt'、 'hello node'、function(err){console.log( "保存され、サーバーが応答性が高い!");}); // bad:synchronallyfs.writefilesync( 'message.txt'、 'hello node'); console.log( "保存しましたが、すべてのリクエストをブロックしただけです!");初期化ログには、実装時にディスクにコンテンツを書き込むための同期呼び出しが含まれています。パフォーマンステストを行わなければ、この問題を無視するのは簡単です。開発者ボックスでnode.jsインスタンスを標準テストとして使用する場合、この同期呼び出しにより、パフォーマンスは毎秒数千のリクエストから数十個にしか低下します。
2。ソケットプールを閉じます
node.jsのHTTPクライアントは、ソケットプールを自動的に使用します。デフォルトでは、ホストごとに5つのソケットのみを制限します。ソケットの再利用は、制御下のリソースの増加を引き起こす可能性がありますが、同じホストからの同時リクエストに対処する必要がある場合は、一連のボトルネックにつながります。この場合、マックスソケットの値を増やすか、ソケットプールを閉じることをお勧めします。
//ソケットプーリングvar http = require( 'http'); var options = {.....}; options.agent = false; var req = http.request(options)を無効にする3.静的リソースにnode.jsを使用させないでください
CSSや画像などの静的リソースについては、node.jsの代わりに標準Webサーバーを使用します。たとえば、LinkedIn MobileはNginxを使用します。また、コンテンツ配信ネットワーク(CDN)を使用して、世界中の静的リソースをサーバーにコピーできます。これには2つの利点があります。(1)node.jsサーバーの負荷を減らすことができます(2)CDNは、ユーザーに近いサーバーで静的コンテンツを配信して、待機時間を短縮できます。
4.クライアントをレンダリングします
サーバーのレンダリングとクライアントレンダリングの違いをすばやく比較しましょう。 node.jsを使用してサーバー側にレンダリングする場合、リクエストごとにHTMLページを送信します。
<! - 完全にサーバー側にレンダリングされた単純なウェブページの例 - > <!doctype html> <html> <head> <title> linkedin mobile> </head> <body> <div> <img src = "http://mobile-cdn.linkedin.com/images/linkedin.png </div> </body> </html>
ユーザーの名前を除き、このページのすべての内容を観察することに注意してください。残りは静的です。各ユーザーが過負荷にし、ページは同じです。したがって、より効果的なアプローチは、node.jsがJSONフォームのページで必要な動的コンテンツのみを返すようにすることです。
{"name": "John"}
ページの残りの部分 - すべての静的HTMLタグ - は、JavaScriptテンプレート(Underscore.jsテンプレートなど)に配置できます。
<! - クライアントサイドをレンダリングできるJavaScriptテンプレートの例 - > <!doctype html> <html> <head> <head> <title> linkedin mobile </head> <body> <div> <img src = "http://mobile-cdn.linkedin.com/image/ dibedin.png"/</<pentin. %>! </div> </body> </html>
パフォーマンスの改善はこれらの場所から生まれます。3番目のポイントが示すように、静的JavaScriptテンプレートは、Webサーバー(NGINXなど)を介してサーバー側で提供されるか、より良いCDNで実装できます。さらに、JavaScriptテンプレートはブラウザにキャッシュされたり、ローカルに保存されたりできます。すべての最初のページがロードされた後、クライアントに送信する必要があるデータのみがJSONであり、これが最も効果的です。この方法では、CPU、IO、およびnode.jsの負荷を大幅に削減できます。
5。GZIPを使用します
多くのサーバーとクライアントは、GZIPをサポートしてリクエストと回答を圧縮しています。クライアントに応答している場合でも、リクエストをリモートサーバーに送信している場合でも、必ず完全に使用してください。
6。並列化
すべてのブロッキング操作 - リクエスト、DBコール、およびファイルシステムアクセスの並列化をリモートサービスに送信するようにしてください。これにより、すべてのブロッキング操作の待機時間ではなく、最も遅いブロッキング操作の待機時間が短縮されます。コールバックとエラー処理をクリーンに保つために、ステップを使用してトラフィックを制御します。
7.セッションの自由化
LinkedIn Mobileは、Expressフレームワークを使用して、リクエスト/返信サイクルを管理します。多くの明確な例には、次の構成が含まれます。
app.use(express.session({secret: "keyboard cat"}));
デフォルトでは、セッションデータはメモリに保存され、特にユーザーの数が増えると、サーバーに大きなオーバーヘッドが追加されます。 MongodbやRedisなどの外部セッションストアを使用できますが、各リクエストはリモートコールのオーバーヘッドになり、セッションデータを取得します。可能であれば、最良のオプションは、すべてのステートレスデータをサーバー側に保存することです。上記のエクスプレス構成を含めないことでセッションを自由化することで、パフォーマンスが向上します。
8。バイナリモジュールを使用します
可能であれば、JavaScriptモジュールをバイナリモジュールに置き換えます。たとえば、JavaScriptで書かれたSHAモジュールからnode.jsのコンパイルされたバージョンに変換すると、パフォーマンスが大きく跳躍しています。
//ビルトインまたはバイナリモジュールcrypto = require( 'crypto'); var hash = crypto.createhmac( "sha1"、key).update(signaturebase).digest( "base64");
9.クライアントライブラリを標準V8 JavaScriptに置き換えます
JavaScript環境では、たとえば一部のブラウザがForeach、Map、Reduceなどの関数をサポートするため、多くのJavaScriptライブラリがWebブラウザーで使用するために作成されていますが、一部のブラウザはそうではありません。したがって、クライアントライブラリは通常、ブラウザの違いを克服するために多くの非効率的なコードを使用します。一方、node.jsでは、どのJavaScriptメソッドが効果的であるかを正確に知ることができます。V8JavaScriptエンジンはnode.jsをサポートして、ECMA-262の第5版で指定されたECMAScriptを実装します。クライアントライブラリを標準のV8 JavaScript関数に直接交換すると、パフォーマンスの大幅な改善が見つかります。
10。コードを小さく軽くしてください
モバイルデバイスを使用すると、アクセスが遅く、遅延が高くなり、コードを小さく軽く保つようになります。サーバーコードについても同じ哲学が維持されています。時折あなたの決定を振り返って、「このモジュールが本当に必要ですか?」、「このフレームワークを使用するのはなぜですか?そのオーバーヘッドは使用する価値がありますか?」、「簡単な方法で実装できますか?」通常、小型コードと軽いコードは、より効率的で高速です。
試してみてください
モバイルアプリを速くするために一生懸命努力しています。 iPhoneアプリ、Androidアプリ、HTML5モバイルバージョンなどのプラットフォームで試して、私たちのやり方を知らせてください。