Développement JavaScript responsable Partie 1

Les chiffres nous indiquent que la croissance du code JavaScript a un mauvais effet sur les performances des projets Web. Si cela continue, puis très bientôt, lors du chargement de la page du milieu, au moins 400 Ko de code JS seront transférés. Et ce n'est que la quantité de données transférées. Comme d'autres ressources textuelles, le code JavaScript est presque toujours transmis sous forme compressée. La compression est probablement la seule chose qui est généralement effectuée correctement lors du transfert de code du serveur vers le client.

image

Malheureusement, bien que la réduction du temps de transfert de certaines ressources contribue sérieusement à ce que nous appelons les «performances», la compression n'affecte pas le temps que prend le navigateur pour analyser et traiter le script après son chargement complet. .

Si le serveur envoie 400 Ko de code JS compressé au client, la quantité réelle de code que le navigateur doit traiter après la décompression des données reçues sera dans la zone mégaoctets. La façon dont différents appareils gèrent ce type de travail dépend des appareils eux-mêmes. Beaucoup a été écrit à ce sujet, mais nous ne pouvons que dire avec certitude que le temps nécessaire, même pour analyser la quantité de code qui est assez habituelle pour son temps, varie considérablement entre les différents appareils.

Jetez un œil, par exemple, à ce simple projet que je fais. Pendant le chargement de la page, environ 23 Ko de code JS non compressé sont transférés au client. Chrome, fonctionnant sur le MacBook Pro, qui est sorti à la mi-2017, traite cette assez petite quantité de code en environ 25 ms. Cependant, sur le smartphone Android Nokia 2 , un chiffre similaire atteint 190 ms. Cela ne veut pas dire qu'elle est très petite, mais en tout cas, la page devient interactive assez rapidement.

Maintenant, une question importante. Que pensez-vous, comment un simple smartphone Nokia 2 gère-t-il les pages modernes moyennes? En fait - tout simplement horrible. La navigation sur des pages Web, même sur une connexion Internet rapide, oblige l'utilisateur à faire preuve de patience, car travailler avec des pages chargées de code JavaScript ne devient possible qu'après une longue période d'attente.


Aperçu des performances de Nokia 2 lors de l'affichage d'une page contenant une grande quantité de code JS, dont le traitement bloque le thread principal

Bien que les appareils avec lesquels ils utilisent pour parcourir les pages Web et les réseaux par lesquels les données sont transmises se soient considérablement améliorés ces dernières années, des études montrent que toutes ces améliorations sont «absorbées» par de grandes quantités de code JS incluses dans les pages. Nous devons utiliser JavaScript de manière responsable. La responsabilité commence par une compréhension de ce que nous créons et de la façon dont nous le faisons.

Comparaison de l'idéologie des "sites" et des "applications"


Des choses étranges se produisent avec des termes inexacts que nous utilisons pour nommer quelque chose, bien que leur signification, à un niveau intuitif, soit claire pour tout le monde. Parfois, nous surchargeons le sens du mot «abeille», en l'appelant «abeilles» et guêpes, même si la différence entre les abeilles et les guêpes est très importante. La prise en compte de ces différences peut conduire au fait que les «abeilles» et les «guêpes» agiront différemment. Par exemple, nous allons détruire un nid de frelons, mais si nous parlons d'abeilles, les insectes sont beaucoup plus utiles et vulnérables, leur nid situé au mauvais endroit sera probablement décidé de ne pas détruire, mais de le transférer quelque part.

Une liberté similaire peut être observée dans la façon dont nous utilisons les termes «site Web» et «application Web». Les différences entre ces concepts sont beaucoup moins évidentes que les différences entre les vraies guêpes et les abeilles, mais si ces concepts sont combinés, cela peut entraîner des conséquences très désagréables. Les problèmes commencent lorsque nous nous permettons quelque chose, selon qu'un certain projet est «juste un site Web» ou «une application Web complète». Si vous créez un site d'informations pour une entreprise, il est fort probable que vous ne vous appuyiez pas sur un cadre puissant pour gérer les modifications DOM ou pour implémenter le routage sur le client. J'espère au moins. L'utilisation d'outils mal adaptés à la résolution de certains problèmes nuira non seulement à ceux qui utiliseront le site, mais affectera aussi probablement gravement le processus de développement.

Lors du développement d'une application Web, tout semble différent. Nous installons des packages, qui s'accompagnent de l'ajout de centaines, sinon de milliers, de dépendances au projet. De plus, nous ne sommes même pas sûrs de la sécurité de certains d'entre eux. Nous écrivons des configurations complexes pour les bundlers. Lorsque vous travaillez dans un environnement de développement fou et omniprésent, vous avez besoin de connaissances et d'attention afin de vous assurer que ce qui a été collecté est rapide, que le projet fonctionnera là où il devrait fonctionner. En cas de doute, exécutez la commande npm ls --prod dans le répertoire racine de votre projet et voyez si vous pouvez nommer l'objectif d'utiliser tout ce que cette commande affiche. Même si vous pouvez le faire, cela ne s'applique pas aux scripts tiers. Je suis sûr que plusieurs de ces scripts sont également utilisés dans votre projet.

Nous oublions que les sites Web et les applications Web occupent la même «niche écologique». Les deux sont sous la même influence de l'environnement, qui se compose d'une variété de réseaux et d'appareils. De telles restrictions ne disparaîtront pas si nous décidons d'appeler ce que nous développons en tant qu '«application», et les appareils de nos utilisateurs ne deviendront pas magiquement beaucoup plus rapides si nous appelons le «site Web» une «application».

Il est de notre responsabilité de savoir qui utilise ce que nous créons, nous devons tenir compte du fait que les conditions dans lesquelles différents utilisateurs se connectent à Internet peuvent différer de celles sur lesquelles nous comptons. Lors de la création de quelque chose, nous devons connaître le but pour lequel nous le créons, et après cela, nous devons développer ce qui aide à atteindre ce but - même si le développement s'avère ne pas être une entreprise aussi passionnante .

Cela signifie la nécessité de réévaluer notre dépendance à l'égard de JavaScript, et comment son utilisation, en particulier au détriment du HTML et du CSS, peut nous conduire à l'utilisation de modèles irrationnels qui nuisent aux performances et à l'accessibilité des projets Web.

Ne laissez pas les cadres vous imposer des modèles irrationnels


J'ai été témoin de la découverte de choses étranges dans des bases de code lorsque je travaillais avec des équipes dépendantes de frameworks afin de les aider à être plus productives. Bon nombre de ces découvertes ont un point commun, à savoir que la façon dont elles sont écrites entraîne souvent des problèmes de disponibilité et de performances des sites. Par exemple, considérez le composant React suivant:

import React, { Component } from "react"; import { validateEmail } from "helpers/validation"; class SignupForm extends Component {  constructor (props) {    this.handleSubmit = this.handleSubmit.bind(this);    this.updateEmail = this.updateEmail.bind(this);    this.state.email = "";  }  updateEmail (event) {    this.setState({      email: event.target.value    });  }  handleSubmit () {    //      -      if (validateEmail(this.state.email)) {      // ...    }  }  render () {    return (      <div>        <span class="email-label">Enter your email:</span>        <input type="text" id="email" onChange={this.updateEmail} />        <button onClick={this.handleSubmit}>Sign Up</button>      </div>    );  } } 

Vous trouverez ici plusieurs problèmes notables concernant l'accessibilité du projet:

  1. Un formulaire qui n'utilise pas l'élément <form> n'est plus un formulaire. En fait, vous pouvez résoudre ce problème en spécifiant simplement le role = "form" de l'élément parent <div> , mais si vous créez un formulaire, et que ce que nous voyons ressemble définitivement à un formulaire, utilisez l'élément <form> , en le définissant en conséquence attribue l' action et la method . L'attribut action joue ici un rôle crucial, car il permet au formulaire de faire au moins quelque chose même si JavaScript n'est pas disponible (naturellement, si le composant a été rendu sur le serveur).
  2. La <span> ne remplace pas la <label> , qui fournit certaines fonctionnalités concernant la disponibilité des projets que <span> ne possède pas.
  3. L'élément <button> sans l'attribut type="submit" n'est qu'un bouton, en cliquant sur celui qui appelle le gestionnaire d'événements qui lui est lié. Si nous voulons faire quelque chose avec les données avant de soumettre le formulaire, nous devons affecter l'attribut type="submit" au bouton et déplacer le code du gestionnaire d'événements onClick vers le gestionnaire d'événements de formulaire onSubmit .
  4. Soit dit en passant, pourquoi utiliser JavaScript pour vérifier les adresses e-mail, alors que HTML5 met à notre disposition des contrôles qui prennent en charge la vérification des données d'entrée dans presque tous les navigateurs - jusqu'à IE10? Nous voyons ici une occasion manquée de profiter des fonctionnalités qui sont déjà dans le navigateur et d'appliquer le type d'élément approprié, ainsi que l'attribut requis . Cependant, en utilisant de telles constructions, gardez à l'esprit que la configuration de leur interaction normale avec les lecteurs d'écran nécessitera un certain effort .

Compte tenu de ce qui précède, nous refactorisons le code du composant:

 import React, { Component } from "react"; class SignupForm extends Component { constructor (props) {   this.handleSubmit = this.handleSubmit.bind(this); } handleSubmit (event) {   //    ,         XHR   // (      ,     ,     JS).   event.preventDefault();   //  … } render () {   return (     <form method="POST" action="/signup" onSubmit={this.handleSubmit}>       <label for="email" class="email-label">Enter your email:</label>       <input type="email" id="email" required />       <button type="submit">Sign Up</button>     </form>   ); } } 

Maintenant, le fait que ce composant s'affiche non seulement s'avère plus accessible, mais moins de code JS est utilisé pour implémenter les mêmes fonctionnalités qu'auparavant. Dans un monde qui s'est littéralement noyé dans JavaScript, se débarrasser de quelques lignes de code devrait être considéré comme quelque chose de positif. Le navigateur nous offre de nombreuses opportunités , et nous devons nous efforcer d'utiliser ces opportunités aussi souvent que possible.

Je ne veux pas dire ici que les problèmes d'accessibilité des pages se posent exclusivement lors de l'utilisation de certains frameworks. Je veux dire, en s'appuyant trop sur JavaScript, le développeur, par conséquent, passera simplement à côté de nombreuses fonctionnalités HTML et CSS importantes. Ces lacunes dans les connaissances conduisent souvent à des erreurs, d'ailleurs, nous ne soupçonnons même pas ces erreurs. Les frameworks peuvent être des outils utiles qui augmentent la productivité des développeurs, mais l'étude constante des capacités des technologies Web de base est extrêmement importante pour créer des produits pratiques et utilisables, quels que soient les outils auxiliaires utilisés dans leur développement.

Faites confiance à la puissance de la plateforme web et donnez à vos projets un bel avenir


Puisque nous parlons de cadres, il convient de noter que la plate-forme Web, en soi, est également un cadre énorme. Comme indiqué dans la section précédente, nous nous trouvons dans une meilleure position si nous pouvons compter sur des modèles établis pour travailler avec les capacités de balisage et de navigateur. Une alternative à ces fonctionnalités standard consiste à les réinventer. Il va sans dire qu'une telle «invention» est lourde de difficultés considérables. Mais que se passerait-il si de tels problèmes, chacun à sa manière, étaient résolus par les auteurs de tous les packages JavaScript que nous installons?

ApplicationsApplications d'une seule page


L'une des faiblesses des développeurs qu'ils peuvent facilement se permettre est l'utilisation du modèle Single Page Application (SPA), même dans les projets pour lesquels ce modèle ne convient pas. Bien entendu, ces projets bénéficient du fait qu'ils sont perçus par les utilisateurs comme plus productifs du fait du routage effectué par le client. Mais quels sont les inconvénients de l'utilisation du modèle SPA? Les capacités de navigation de page intégrées du navigateur, bien que construites sur un modèle synchrone, offrent au projet une tonne d'avantages. L'un d'eux est que la gestion de l'historique des visites se fait à travers la mise en place d' un cahier des charges complexe . Les utilisateurs sans JavaScript, qu'ils l'aient désactivé eux-mêmes ou non , ne perdront pas la possibilité de travailler avec le projet. Pour qu'une application d'une page soit disponible dans les navigateurs avec JavaScript désactivé, il s'avère soudain qu'une attention considérable doit être accordée au rendu du serveur.


Comparaison des différentes options de chargement d'une application expérimentale sur un canal de communication lent. Le rendu de l'application à gauche dépend entièrement de JavaScript. L'application de droite est rendue sur le serveur, mais utilise ensuite, sur le client, la méthode hydrate () pour connecter les composants au balisage déjà créé sur le serveur

Ici, vous pouvez voir que l'application, qui est rendue sur le client, affiche pendant quelques secondes à l'utilisateur un écran vide, puis affiche l'interface terminée.

Une application qui est restituée sur le serveur et rendue opérationnelle sur le client affiche rapidement les principaux éléments de l'interface, mais vous pouvez l'utiliser après environ le même temps que l'application qui est rendue entièrement sur le client.

La disponibilité de l'application souffre également si le routeur situé sur le client ne peut pas informer l'utilisateur de ce qui a changé sur la page qu'il consulte. Cela peut obliger l'utilisateur à s'appuyer sur des technologies d'assistance afin de savoir ce qui a changé exactement sur la page, par conséquent, le travail de l'utilisateur avec le site est beaucoup plus compliqué.

De plus, vous pouvez immédiatement rencontrer notre vieil ennemi - une charge excessive sur le système. Certains routeurs clients sont très petits. Mais si vous faites un projet sur React , utilisez un routeur compatible et, éventuellement, une bibliothèque pour gérer l'état de l'application, cela signifie que vous devez accepter qu'il contiendra une certaine quantité de code de service, à partir de laquelle vous ne pouvez pas obtenir n'importe où. A savoir, dans ce cas, il s'agit d'environ 135 Ko de ce code. Analysez soigneusement les projets que vous créez et si le routage client vaut la charge supplémentaire sur le système. Il arrive généralement qu'il vaut mieux refuser le système de routage client.

Si vous êtes inquiet des sentiments de l'utilisateur, si vous voulez que le site lui paraisse rapide, alors vous pouvez vous fier à l'attribut link rel = prefetch , qui vous permet d'organiser le préchargement de documents à partir de la même source. L'utilisation de cet attribut a un impact énorme sur l'amélioration de la productivité du projet, perçue par les utilisateurs, car les pages liées à l'utilisation de cet attribut, lorsque vous cliquez sur ces liens, sont instantanément chargées à partir du cache. De plus, comme le préchargement des données a une faible priorité, il est peu probable qu'il soit en concurrence pour la bande passante avec des ressources importantes.


Le code HTML référencé par écrit / est préchargé lorsque vous visitez la page principale du site. Lorsqu'un utilisateur clique sur le lien correspondant, le code HTML est instantanément chargé à partir du cache du navigateur

Le principal problème qui peut survenir avec les pages de préchargement, et dont vous devez être conscient, est qu'un tel chargement peut s'avérer être une perte de temps et de ressources. Pour le résoudre, vous pouvez, par exemple, utiliser le petit script Quicklink de Google, qui atténue ce problème. Il vérifie si le client actuel utilise une connexion lente, si le mode d'enregistrement des données est activé et, par défaut, vous permet d'éviter de précharger des documents à partir de sources autres que la page source.

Afin de rendre le site rapide aux yeux des utilisateurs qui le visitent plusieurs fois, vous pouvez faire appel à des techniciens de maintenance . Ils peuvent être utilisés indépendamment du fait que le projet utilise ou non un système de routage client, étant donné que vous connaissez certaines des fonctionnalités des techniciens de maintenance. En effectuant la mise en cache des itinéraires au moyen de techniciens de service, nous obtenons bon nombre des mêmes avantages que ceux typiques du préchargement des matériaux de certains liens, mais nous avons des capacités beaucoup plus étendues pour travailler avec les demandes et les réponses. Que vous perceviez votre site comme une «application» ou non, le doter d'un technicien est probablement un exemple de l'un des cas d'utilisation JavaScript les plus critiques de notre époque.

▍JavaScript n'est pas conçu pour la mise en page


Si nous installons un package JS conçu pour résoudre les problèmes liés à la mise en page, alors il est temps pour nous d'être très prudents et de nous demander ce que nous essayons de réaliser avec ce package. CSS a été créé spécifiquement pour la création de mises en page, afin de l'utiliser efficacement, vous n'avez pas besoin d'abstractions. La plupart des tâches de création de mises en page qu'ils essaient de résoudre à l'aide de JavaScript, telles que le placement d' éléments, leur alignement, l'ajustement de leurs tailles, comme la manipulation de texte, ou même la création complète de mises en page à l' aide de JavaScript, peuvent désormais être accomplies à l'aide de CSS. Les outils modernes pour créer des mises en page comme Flexbox et Grid sont bien pris en charge par les navigateurs, nous n'avons donc pas besoin de développer des projets basés sur des cadres pour travailler avec des mises en page. Soit dit en passant, CSS est également un cadre. Lorsque nous avons à notre disposition une telle opportunité que les demandes de propriété , l'amélioration progressive des dispositions pour soutenir de nouveaux moyens de formation, il s'avère, n'est pas si difficile .

 /*   , ,   ,        CSS Grid. */ /*  @supports  ,     CSS Grid,     . */ @supports (display: grid) { /*      */ @media (min-width: 40em) {   /*       CSS Grid */ } } 

L'utilisation de JavaScript pour résoudre les problèmes de création de mises en page et de personnalisation de leur apparence n'est pas nouvelle. C'est ce que nous avons fait en 2009, lorsque nous vivions dans une atmosphère d'auto-illusion, en disant que chaque site devrait ressembler à IE6 ainsi qu'aux navigateurs les plus avancés de l'époque. Si aujourd'hui, en 2019, nous continuons à développer des sites afin qu'ils se ressemblent dans tous les navigateurs, cela signifie que nous devons reconsidérer nos objectifs. Il y aura toujours des navigateurs qui doivent être pris en charge et qui n'ont pas les mêmes capacités que les navigateurs les plus modernes. La similitude externe totale des projets sur toutes les plateformes n'est pas seulement un gaspillage d'énergie, c'est aussi un ennemi fondamental de l'idée d' améliorations progressives .

Conclusion: je ne vais pas devenir un tueur de JavaScript


Ne vous méprenez pas, je n'appartiens pas aux ennemis de JavaScript. Grâce à ce langage, j'ai construit une carrière et, pour être honnête, JavaScript, depuis plus de dix ans, m'apporte beaucoup de plaisir. Comme pour toute relation à long terme, plus je passe de temps à travailler avec JavaScript, mieux je le connais. C'est un langage mature avec de nombreuses fonctionnalités qui, chaque année, s'améliore.

Cependant, il me semble parfois que quelque chose a mal tourné avec notre relation JavaScript. Je le critique. Ou, plus précisément, je critique la tendance actuelle à considérer JavaScript comme le principal outil de construction de sites, auquel on a recours en premier lieu, sans regarder autre chose. Lorsque j'ai analysé un autre paquet qui ressemblait à une guirlande de Noël déroutante, il est devenu clair pour moi que le Web était intoxiqué par JavaScript. Nous utilisons cette langue pour presque toutes les raisons, même dans les cas où les circonstances ne l'exigent pas. Parfois, je pense à la gravité des conséquences de cette attitude envers JS.

J'ai l'intention de continuer à écrire sur JavaScript et le développement Web, de continuer à chercher des moyens d'utiliser rationnellement les technologies Web. J'espère qu'ensemble, nous améliorerons le Web moderne.

Chers lecteurs! Pensez-vous que le Web moderne est vraiment surchargé de code JavaScript?

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


All Articles