Maison  >  Article  >  interface Web  >  10 conseils d'optimisation des performances pour nodejs_node.js

10 conseils d'optimisation des performances pour nodejs_node.js

WBOY
WBOYoriginal
2016-05-16 16:41:501443parcourir

Voici 10 règles de performances que nous suivons lors de l'utilisation de Node.js :

1. Évitez d'utiliser du code synchrone

De par sa conception, Node.js est monothread. Pour permettre à un seul thread de gérer de nombreuses requêtes simultanées, vous ne pouvez jamais demander à un thread d'attendre des opérations bloquantes, synchrones ou de longue durée. Une particularité de Node.js est qu'il est conçu et implémenté de haut en bas pour réaliser une implémentation asynchrone. Cela le rend idéal pour les programmes événementiels.

Malheureusement, il est toujours possible que des appels synchrones/bloquants se produisent. Par exemple, de nombreuses opérations du système de fichiers ont des versions à la fois synchrones et asynchrones, telles que writeFile et writeFileSync. Même si vous utilisez du code pour contrôler la méthode de synchronisation, il est toujours possible d'utiliser par inadvertance une bibliothèque de fonctions externe qui bloque les appels. Lorsque vous faites cela, l’impact sur les performances est énorme.

// 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!");

Notre implémentation du journal d'initialisation a inclus par inadvertance un appel synchrone pour écrire le contenu sur le disque. Si nous ne testons pas les performances, il sera facile d’ignorer ce problème. Lorsqu'il est testé sur une instance node.js dans la boîte du développeur, cet appel synchrone entraînera une baisse des performances de milliers de requêtes par seconde à seulement quelques dizaines.

2. Fermez le pool de sockets

Le client http Node.js utilise automatiquement le pooling de sockets : par défaut, il limite chaque hôte à 5 sockets. Même si la réutilisation des sockets permet de contrôler l'augmentation des ressources, elle peut entraîner une série de goulots d'étranglement si vous devez gérer de nombreuses requêtes simultanées de données provenant du même hôte. Dans ce cas, c'est une bonne idée d'augmenter la valeur de maxSockets ou de désactiver le pool de sockets :

// Disable socket pooling
 
var http = require('http');
var options = {.....};
options.agent = false;
var req = http.request(options)

3. Ne laissez pas les ressources statiques utiliser Node.js

Pour les ressources statiques telles que les CSS et les images, utilisez le serveur Web standard au lieu de Node.js. Par exemple, LinkedIn Mobile utilise nginx. Nous utilisons également des réseaux de diffusion de contenu (CDN), qui peuvent copier des ressources statiques sur des serveurs du monde entier. Cela présente deux avantages : (1) Cela peut réduire la charge sur notre serveur node.js (2) Les CDN peuvent réduire le temps d'attente en permettant de diffuser du contenu statique sur des serveurs plus proches des utilisateurs.

4. Rendu sur le client

Comparons rapidement les différences entre le rendu serveur et le rendu client. Si nous utilisons node.js pour le rendu côté serveur, pour chaque requête, nous renverrons une page HTML comme la suivante :

<!-- 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>

Veuillez noter que tout le contenu de cette page, à l'exception du nom de l'utilisateur, est un contenu statique : le contenu est le même pour chaque utilisateur et chaque rechargement de page. Par conséquent, il est plus efficace de laisser Node.js renvoyer uniquement le contenu dynamique requis par la page sous forme JSON.

{"name": "Jean"}
Le reste de la page (tous les balises HTML statiques) peuvent être placés dans un modèle JavaScript (tel que le modèle 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>

L'amélioration des performances vient de ces endroits : comme mentionné dans le troisième point, les modèles JavaScript statiques peuvent être fournis côté serveur via le serveur Web (comme nginx), ou implémentés à l'aide d'un meilleur CDN. De plus, les modèles JavaScript peuvent être mis en cache dans le navigateur ou stockés localement après le chargement initial de la page, les seules données qui doivent être envoyées au client sont JSON, ce qui sera le plus efficace. Cette méthode peut réduire considérablement la charge du CPU, des E/S et de Node.js.

5. Utilisez gzip

De nombreux serveurs et clients prennent en charge gzip pour compresser les requêtes et les réponses. Qu'il s'agisse de répondre à des clients ou d'envoyer des requêtes à des serveurs distants, assurez-vous de l'utiliser à son plein potentiel.

6. Parallélisation

Essayez de paralléliser toutes vos opérations de blocage - requêtes vers des services distants, appels à la base de données, accès au système de fichiers. Cela réduira le temps d'attente de l'opération de blocage la plus lente, plutôt que le temps d'attente de toutes les opérations de blocage. Pour garder les rappels et la gestion des erreurs propres, nous utilisons Step pour contrôler le flux.

7.Libéralisation des sessions

LinkedIn Mobile utilise le framework Express pour gérer le cycle demande/réponse. De nombreux exemples express incluent la configuration suivante :

app.use(express.session({ secret : "clavier chat" }));
Par défaut, les données de session sont stockées en mémoire, ce qui ajoute une énorme surcharge au serveur, surtout à mesure que le nombre d'utilisateurs augmente. Vous pouvez utiliser un magasin de sessions externe, tel que MongoDB ou Redis, mais chaque requête entraînera la surcharge d'un appel à distance pour récupérer les données de session. Dans la mesure du possible, la meilleure option consiste à stocker toutes les données apatrides côté serveur. En libérant la session en n'incluant pas la configuration express ci-dessus, vous constaterez de meilleures performances.

8. Utiliser des modules binaires

Si possible, remplacez les modules JavaScript par des modules binaires. Par exemple, lorsque l'on passe d'un module SHA écrit en JavaScript à une version compilée pour Node.js, on constate un énorme bond en performances :

// Use built in or binary modules
var crypto = require('crypto');
var hash = crypto.createHmac("sha1",key).update(signatureBase).digest("base64");

9. Remplacez la bibliothèque client par du JavaScript V8 standard

De nombreuses bibliothèques JavaScript sont créées pour être utilisées sur les navigateurs Web car l'environnement JavaScript diffère : par exemple, certains navigateurs prennent en charge des fonctions telles que forEach, map et reduction, mais certains navigateurs ne le font pas. Ainsi, les bibliothèques clientes utilisent souvent beaucoup de code inefficace pour surmonter les différences entre les navigateurs. Dans Node.js, en revanche, vous savez exactement quelles méthodes JavaScript sont valides : le moteur JavaScript V8 prend en charge l'implémentation d'ECMAScript par Node.js comme spécifié dans ECMA-262 5e édition. Remplacez simplement la bibliothèque client par des fonctions JavaScript V8 standard et vous constaterez des améliorations significatives des performances.

10. Gardez votre code petit et léger

L'utilisation d'appareils mobiles peut entraîner un accès lent et une latence élevée, ce qui nous oblige à garder notre code petit et léger. Gardez également la même philosophie pour le code du serveur. Revenez de temps en temps sur vos décisions et posez-vous des questions telles que : « Avons-nous vraiment besoin de ce module ? », « Pourquoi utilisons-nous ce cadre et les frais généraux en valent-ils la peine ? », « Pouvons-nous utiliser un moyen plus simple pour y parvenir ? " Un code plus petit et plus léger est généralement plus efficace et plus rapide.

Essayez-le

Nous travaillons dur pour rendre nos applications mobiles rapides. Essayez-le sur l'application iPhone, l'application Android et la version mobile HTML5 et dites-nous comment vous vous en sortez.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn