Optimisation ou comment ne pas se tirer une balle dans le pied

Bonne journée à tous. Aujourd'hui, je veux vous parler d'optimisation. Qu'est-ce que c'est, pourquoi est-il nécessaire, et surtout, comment s'assurer qu'il ne fait pas douloureusement souffrir alors.


Tout d'abord, nous comprendrons ce qu'est l'optimisation en général et ce qu'est l'optimisation dans JS. Ainsi, l'optimisation est l'amélioration de quelque chose selon une caractéristique quantitative. JS a identifié quatre caractéristiques quantitatives pour lui-même:


La quantité de code - il est généralement admis que moins il y a de lignes de code écrites, plus elles sont productives et meilleures. Mon opinion est fondamentalement différente, car en écrivant une ligne de code, vous pouvez créer une telle fuite de mémoire ou un cycle perpétuel que le navigateur meurt simplement.


La vitesse (performance) est la soi-disant complexité de calcul, c'est-à-dire le nombre d'actions que l'analyseur devra effectuer pour exécuter l'instruction.


Vitesse de construction - ce n'est un secret pour personne que presque aucun des projets ne peut se passer de constructeurs comme Webpack ou Gulp, donc cette caractéristique affiche l'exactitude des paramètres du générateur de projet. Croyez-moi, lorsque le serveur est un peu plus intelligent que le moulin à café, cela devient important.


Réutilisation du code - cette caractéristique montre à quel point l'architecture de réutilisation des fonctions, composants et modules est bien construite.
Examinez chacune des catégories plus en détail, nous analyserons les caractéristiques qu'elle comprend et ce dont elle dépend.


Volume de code:

  • Doublage. Combien de code du même type a été écrit à différents endroits;
  • Commentaires Les commentaires dans le code sont bons, mais j'ai rencontré des projets dans lesquels il y avait plus de commentaires que de code;
  • Manque d'unification. Un bon exemple d'un tel problème sont les fonctions similaires, qui ont des nuances en fonction de certaines propriétés.
  • La présence de code mort. Très souvent, dans les projets, il existe des fonctions de débogage ou des fonctions qui ne sont pas du tout utilisées.

Performances:


  • Utilisation du mécanisme de mise en cache du navigateur;
  • Optimisation du code basée sur les environnements dans lesquels il sera exécuté;
  • La présence de fuites de mémoire;
  • Utilisation de travailleurs Web;
  • Utilisation de références aux éléments de l'arborescence DOM;
  • Utilisation de variables globales;
  • La présence d'appels récursifs;
  • Simplification des calculs mathématiques.

Vitesse de construction:


  • Le nombre de dépendances externes;
  • Conversions de code. Cela fait référence au nombre de morceaux et à leur taille, aux conversions css, au collage de fichiers, à l'optimisation graphique et bien plus encore.

Réutilisation du code:


  • Nombre de composants;
  • Répétabilité des composants
  • Flexibilité et personnalisation.

Comme dit dans les articles précédents, pour changer quelque chose, vous devez déterminer le point de départ et comprendre à quel point tout est mauvais. Par où commencer un processus aussi volumineux? Commencez par la chose la plus simple: accélérer le montage et réduire le temps de dépassement du projet. Vous demandez pourquoi cela vaut la peine de commencer par cela? En raison du fait qu'ils dépendent les uns des autres. Réduire la quantité de code augmentera la vitesse de génération des générations et, par conséquent, augmentera votre productivité.


L'optimisation du temps de construction nous introduit inévitablement au concept de construction «à froid» - c'est le processus lorsqu'un projet démarre à zéro et au point que toutes les dépendances sont affectées et que le code est complètement recompilé. Ne confondez pas avec Rebild - il s'agit de reconstruire le code client sans extraire les dépendances externes et autres guirlandes.


Augmenter la vitesse de construction de la construction aidera:


  • Utilisation d'assembleurs modernes. Les technologies ne s'arrêtent pas, et si vous avez le premier webpack, alors lorsque vous passez au quatrième, vous verrez une augmentation agréable qui ne fait déjà rien;
  • Se débarrasser de toutes les dépendances mortes. De temps en temps, les développeurs, essayant de trouver la vérité au fond de la boîte d'acide sulfurique, oublient de nettoyer après leurs propres expériences. le paquet? " Oui, ils ne seront pas inclus dans l'assemblage lui-même, mais le colis sera dégonflé. La question est, pourquoi?
  • Divisez l'assemblage en plusieurs profils en fonction de vos besoins. Minimum deux: prod et dev. Exemple: obfuscation de code. Sur prod, cela est obligatoire, car moins de poids = un chargement plus rapide, mais sur l'obfuscation dev ne interfère et passe le temps de construction sur des manipulations inutiles;
  • Parallélisation des différentes étapes d'assemblage;
  • Utilisation de clients npm pouvant mettre en cache.

Pour accélérer la reconstruction et la génération "à froid", il faudra supprimer les commentaires inutiles et les morceaux de code morts. Cependant, que faire si vous avez un gros projet et qu'il n'est pas possible de l'inspecter vous-même? Dans de tels cas, les analyseurs de code viennent à la rescousse.


Personnellement, j'utilise périodiquement SonarQube , pas le meilleur, mais flexible. Le cas échéant, il peut apprendre les caractéristiques du projet. De temps en temps, il fait des choses qui au moins se tiennent debout, au moins tombent, mais, comme tout instrument, il doit pouvoir l'utiliser et ne pas oublier d'être sceptique quant à ses propos. Malgré tous ses inconvénients, il résiste à la recherche de code mort, de commentaires, de présence de copier-coller et de petites choses, comme l'absence de comparaison stricte.


La différence fondamentale entre SonarQube et ESlint / TSLint / Prettier et d'autres comme eux est qu'il vérifie la qualité du code, isole le doublage, la complexité du calcul et donne également des recommandations sur les changements nécessaires. Les analogues vérifient simplement le code pour les erreurs, la syntaxe et le formatage.


En pratique, je suis tombé sur la codacy , un bon service avec un abonnement gratuit et payant. Il sera utile si vous avez besoin de vérifier quelque chose sur le côté, sans avoir à déployer cette «moissonneuse» à la maison. Il a une interface intuitive, une indication détaillée de ce qui ne va pas avec le code et bien plus encore.


Dans cet article, je n'aborderai pas le sujet de la configuration de la build, des morceaux et du reste, car tout dépend des besoins du projet et du constructeur installé. J'en parlerai peut-être dans d'autres articles.


Les manipulations effectuées ont aidé à accélérer l'assemblage - profit, mais que faire ensuite? Étant donné que les analyseurs peuvent trouver le doublage de code, il sera utile de le placer dans des modules ou composants séparés, augmentant ainsi la réutilisation du code.


Il n'y avait qu'une seule section que nous n'avons pas touchée - la vitesse du code lui-même. Le mécanisme même de l'amener à un sens de la productivité de celui-ci est appelé par tout le mot détesté refactoring. Examinons de plus près ce qui vaut la peine d'être refactorisé et ce qui ne l'est pas.


Règle de vie: si ça marche, ne le touchez pas, ça ne devrait pas vous guider dans ce processus. La première règle en informatique: faites une sauvegarde, puis vous direz merci à vous-même. À l'avant, avant d'effectuer des modifications, effectuez des tests afin de ne pas perdre de fonctionnalité à l'avenir. Alors demandez-vous - comment déterminer les temps de chargement et les fuites de mémoire?


Cela aidera DevTool. Il montrera non seulement une fuite de mémoire, vous indiquera le temps de chargement de la page, le rabattement de l'animation, et si vous avez de la chance, il effectuera un audit pour vous, mais ce n'est pas exact. DevTools a également une fonctionnalité intéressante, telle que la limitation de la vitesse de téléchargement, qui vous permettra de prédire la vitesse de chargement des pages avec une mauvaise connexion Internet.


Nous avons pu identifier les problèmes, maintenant résolvons-les!


Pour commencer, nous allons réduire le temps de chargement en utilisant le mécanisme de mise en cache du navigateur. Le navigateur peut tout mettre en cache et ensuite fournir à l'utilisateur les données du cache. Localstorage et sessionstorage que personne ne vous a pris. Ils vous permettent de stocker certaines des données qui aident à accélérer le SPA lors des téléchargements ultérieurs et à réduire les demandes de serveur inutiles.


Il est jugé nécessaire d'optimiser le code en fonction de l'environnement dans lequel il sera exécuté, mais comme le montre la pratique, il consomme beaucoup de temps et d'efforts, sans apporter une augmentation tangible. Je propose de ne considérer cela que comme une recommandation.
Il est naturellement conseillé d'éliminer toutes les fuites de mémoire. Je ne vais pas me concentrer sur cela, je pense que tout le monde sait comment les éliminer, et sinon, il suffit de google.


Un autre de nos assistants est un webworker. Les travailleurs Web sont des threads appartenant à un navigateur qui peuvent être utilisés pour exécuter du code JS sans bloquer la boucle d'événements. Les travailleurs Web peuvent effectuer des tâches lourdes et longues sur le plan informatique sans bloquer le flux de l'interface utilisateur. En effet, lorsqu'ils sont utilisés, les calculs sont effectués en parallèle. Devant nous, c'est du vrai multithreading. Il existe trois types de travailleurs Web:


  1. Travailleurs dédiés - Les instances de travailleurs Web dédiés sont créées par le processus principal. Seul le processus lui-même peut échanger des données avec eux.
  2. Travailleurs partagés (travailleurs partagés) - L'accès à un travailleur partagé peut être obtenu par n'importe quel processus ayant la même source que le travailleur (par exemple, différents onglets du navigateur, iframe et d'autres travailleurs partagés).
  3. Les travailleurs des services sont des travailleurs événementiels enregistrés en utilisant leur source et leur chemin d'accès. Ils peuvent contrôler la page Web à laquelle ils sont liés en interceptant et en modifiant les commandes de navigation et les demandes de ressources, et en mettant en cache des données qui peuvent être contrôlées très précisément. Tout cela nous donne d'excellents outils pour contrôler le comportement de l'application dans une certaine situation (par exemple, lorsque le réseau n'est pas disponible).

Comment travailler avec eux peut être facilement trouvé sur Internet.


Nous avons en quelque sorte compris les approches et les problèmes des tiers, maintenant je propose de parler du code lui-même.


Tout d'abord, essayez de vous débarrasser des appels directs à l'arborescence DOM, car cette opération prend du temps. Imaginons que vous manipuliez constamment une sorte d'objet dans votre code. Au lieu de travailler avec cet objet par référence, vous tirez constamment l'arborescence DOM pour rechercher cet élément et travailler avec, et nous implémentons le modèle de mise en cache dans le code.


La deuxième étape consiste à se débarrasser des variables globales. ES6 nous a donné une merveilleuse invention de l'humanité appelée variables de bloc (en termes simples, déclarations de variables de var à let et const ).


Et enfin, le plus délicieux. Ici, malheureusement, tout le monde n'a pas assez d'expérience pour comprendre la nuance. Je suis contre l'utilisation de fonctions récursives. Oui, ils réduisent la quantité de code écrit, mais cela ne peut pas se passer d'un hic: souvent ces fonctions récursives n'ont pas de conditions de sortie, elles sont simplement oubliées. Comme dans l'adage «on peut se casser un doigt avec un marteau, mais ce n'est pas un problème de marteau, mais un propriétaire de doigt» ou une blague sur les chats: les fonctions récursives ne sont pas mauvaises, il faut pouvoir les cuisiner.


Malgré toute la puissance des applications frontales modernes, vous ne devez pas oublier les bases. Un exemple clair de gaspillage et d'irrationalité est l'ajout de nouveaux éléments au début du tableau. Qui sait, il a compris, et celui qui ne sait pas - maintenant je vais le dire. Tout le monde sait que les éléments de tableau ont leur propre index, et lorsque nous allons ajouter un nouvel élément de tableau à son début, la séquence d'actions sera la suivante:


  1. Définition de la longueur du tableau
  2. Numérotation de chaque élément.
  3. Décalage de chaque élément du tableau
  4. Insérer un nouvel élément dans un tableau
  5. Réindexation des éléments du tableau.

Résumé:


Il est temps d'arrêter, et pour ceux qui sont à l'aise avec le format des mémos, gardez une liste d'étapes grâce auxquelles vous pouvez comprendre à quel stade d'optimisation vous êtes maintenant et que faire ensuite:


  1. Nous déterminons combien tout est bon / mauvais, supprimons les mesures.
  2. Nous supprimons tout ce qui n'est pas nécessaire: dépendances inutilisées, code mort, commentaires inutiles.
  3. Nous personnalisons et accélérons le temps d'assemblage, configurons différents profils pour les contours.
  4. Nous analysons le code et décidons quelles parties nous allons optimiser et réécrire.
  5. Nous écrivons des tests pour éviter la perte de fonctionnalité.
  6. Nous commençons le refactoring, nous débarrassons des variables globales, des fuites de mémoire, du doublage de code et d'autres ordures, et n'oublions pas la mise en cache.
  7. Nous simplifions la complexité des calculs et apportons tout ce qui est possible au web travailleur.

Tout n'est pas aussi compliqué qu'il n'y paraît à première vue. Votre séquence sera probablement différente de la mienne, ne serait-ce que parce que vous avez votre propre tête sur les épaules. Vous ajouterez de nouveaux éléments ou, à l'inverse, réduirez leur nombre, mais la base de la liste sera similaire. J'ai spécifiquement décrit la division afin que cette activité puisse être menée en parallèle avec le travail principal. Souvent, le client n'est pas prêt à payer pour les retouches, d'accord?


Et enfin.


Je crois en toi et tu réussiras. Pensez-vous que je suis naïf? Je suppose que vous serez surpris, mais depuis que vous avez trouvé cet article, lisez-le jusqu'au bout, cela signifie (j'ai de bonnes nouvelles pour vous) que vous avez des cerveaux et que vous essayez de les développer. Je vous souhaite du succès dans une entreprise aussi difficile que l'optimisation du front!

Source: https://habr.com/ru/post/fr469127/


All Articles