Voici 10 règles de performance que nous suivons lorsque nous utilisons Node.js:
1. Évitez d'utiliser du code synchrone
En termes de conception, Node.js est unique. Pour permettre à un seul thread de gérer de nombreuses demandes simultanées, vous ne pouvez jamais laisser le fil attendre les opérations de blocage, synchrone ou de longue durée. Une caractéristique distinctive de Node.js est qu'elle est conçue et implémentée de haut en bas pour réaliser des asynchrones. Cela le rend très adapté aux programmes de type événement.
Malheureusement, il est toujours possible que des appels synchrones / bloquants se produisent. Par exemple, de nombreuses opérations de système de fichiers ont des versions 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 la bibliothèque de fonctions externes qui bloque les appels par inadvertance. Lorsque vous faites cela, l'impact sur les performances est énorme.
// bon: écrivez des fichiers asynchronelyfs.writeFile ('message.txt', 'Hello node', fonction (err) {console.log ("il est enregistré et le serveur reste réactif!");}); // Bad: écrivez des fichiers synchronishyfs.writeFileSync ('message.txt', 'Hello node'); console.log ("il est enregistré, mais vous avez simplement bloqué toutes les demandes!");Notre journal d'initialisation inclut involontairement un appel synchrone pour écrire du contenu sur disque lorsqu'il est implémenté. Si nous ne faisons pas de tests de performances, il sera facile d'ignorer ce problème. Lorsque vous utilisez une instance Node.js dans la boîte de développeur comme test standard, cet appel synchrone entraînera des performances à passer de milliers de demandes par seconde à seulement quelques dizaines.
2. Fermez la piscine à douille
Le client HTTP de Node.js utilisera automatiquement les pools de socket: par défaut, il ne limitera que 5 sockets par hôte. Bien que la réutilisation des prises puisse entraîner l'augmentation des ressources sous contrôle, si vous devez répondre aux demandes simultanées du même hôte, cela conduira à une série de goulots d'étranglement. Dans ce cas, c'est une bonne idée d'augmenter la valeur des maxsockés ou de fermer le pool de douille:
// Désactiver le regroupement de socket 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 des ressources statiques telles que CSS et Images, utilisez le serveur Web standard au lieu de Node.js. Par exemple, LinkedIn Mobile utilise Nginx. Nous utilisons également des réseaux de livraison de contenu (CDN), qui peuvent copier des ressources statiques dans le monde entier sur les serveurs. Cela présente deux avantages: (1) il peut réduire la charge sur notre serveur Node.js (2) Les CDN peuvent permettre de fournir du contenu statique sur des serveurs plus près de l'utilisateur, réduisant ainsi le temps d'attente.
4. Rendre le client
Comparons rapidement la différence entre le rendu du serveur et le rendu client. Si nous utilisons Node.js pour rendre côté serveur, pour chaque demande, nous renverrons une page HTML comme ce qui suit:
<! - Un exemple d'une page Web simple rendue entièrement du côté serveur -> <! Doctype html> <html> <ead> <Title> LinkedIn Mobile </Title> </mobile-cdn.Linkedin.com/Images/Linkedin.png "/> </ Div> Hellow! John! </div> </ body> </html>
Veuillez faire attention à l'observation de tous les contenus de cette page, à l'exception du nom de l'utilisateur, le reste est statique: le contenu surchargé par chaque utilisateur et la page sont les mêmes. Par conséquent, une approche plus efficace consiste à permettre à Node.js de renvoyer uniquement le contenu dynamique requis par la page sous forme json.
{"name": "John"}
Le reste de la page - toutes les balises HTML statiques - peuvent être placées dans des modèles JavaScript (comme le modèle de sous-ore.js):
<! - Un exemple de modèle JavaScript qui peut être rendu côté client -> <! Doctype html> <html> <adread> <itle> linkedIn mobile </title> </ head> <body> <v> <img src = "http://mobile-cdn.linkedin.com/images/Linkedin. %>! </div> </ body> </html>
L'amélioration des performances provient de ces endroits: comme le dit le troisième point, des modèles JavaScript statiques peuvent être fournis du côté du serveur via le serveur Web (tel que Nginx), ou implémenté avec de meilleurs CDN. De plus, les modèles JavaScript peuvent être mis en cache dans le navigateur ou stockés localement. Une fois toutes les pages initiales chargées, 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 de CPU, IO et Node.js.
5. Utilisez gzip
De nombreux serveurs et clients prennent en charge GZIP pour compresser les demandes et réponses. Que vous répondiez à un client ou que vous envoyiez une demande à un serveur distant, assurez-vous de l'utiliser pleinement.
6. Parallélisation
Essayez de laisser toutes vos opérations de blocage - envoyez des demandes, des appels DB et une parallélisation d'accès au système de fichiers aux services distants. Cela réduira le temps d'attente pour l'opération de blocage la plus lente, plutôt que le temps d'attente pour toutes les opérations de blocage. Pour garder les rappels et la gestion des erreurs propres, nous utilisons l'étape pour contrôler le trafic.
7. Libéralisation de session
LinkedIn Mobile utilise le cadre express pour gérer les cycles de demande / réponse. De nombreux exemples express incluent la configuration suivante:
app.use (express.Session ({secret: "clavier cat"}));
Par défaut, les données de session sont stockées en mémoire, ce qui ajoute d'énormes frais généraux au serveur, d'autant plus que le nombre d'utilisateurs augmente. Vous pouvez utiliser un magasin de session externe, tel que MongoDB ou Redis, mais chaque demande entraînera les frais généraux des appels distants pour obtenir des données de session. Lorsque cela est possible, la meilleure option consiste à stocker toutes les données sans état du côté serveur. En libéralisant la session en n'incluant pas la configuration express ci-dessus, vous verrez de meilleures performances.
8. Utiliser des modules binaires
Si possible, remplacez les modules JavaScript par des modules binaires. Par exemple, lorsque nous convertissons d'un module SHA écrit en javascript en une version compilée de Node.js, nous voyons un grand saut en avant en performance:
// Utilisez des modules de modules binaires
9. Remplacer la bibliothèque client par JavaScript V8 standard
De nombreuses bibliothèques JavaScript sont créées pour une utilisation sur les navigateurs Web car dans les environnements JavaScript, par exemple, certains navigateurs prennent en charge les fonctions telles que ForEach, Map et Réduire, mais certains navigateurs ne le font pas. Par conséquent, les bibliothèques clients utilisent généralement beaucoup de code inefficaces pour surmonter les différences de navigateur. D'un autre côté, dans Node.js, vous pouvez savoir exactement quelles méthodes JavaScript sont efficaces: le moteur JavaScript V8 prend en charge Node.js pour implémenter l'ECMAScript spécifié dans la cinquième édition d'ECMA-262. Remplacez directement la bibliothèque client par des fonctions JavaScript V8 standard, vous trouverez des améliorations de performances significatives.
10. Gardez votre code petit et léger
L'utilisation d'un appareil mobile rendra l'accès lent et la latence élevée, ce qui nous dit de garder notre code petit et léger. La même philosophie est maintenue pour le code du serveur. Revenons de temps en temps sur votre décision et posez-vous des questions comme: "Avons-nous vraiment besoin de ce module?", "Pourquoi utilisons-nous ce cadre? Le code petit et léger est généralement plus efficace et rapide.
Essayez-le
Nous travaillons dur pour rendre nos applications mobiles rapidement. Essayez-le sur des plates-formes telles que les applications iPhone, les applications Android et les versions mobiles HTML5 pour nous faire savoir comment nous allons.