Top 8 des erreurs les plus courantes commises par les développeurs de Backbone.js
Publié: 2022-03-11Backbone.js est un framework minimaliste qui vise à fournir un ensemble simple de structures de données et de fonctionnalités que vous pouvez utiliser pour créer le front-end d'une application Web structurée. Prêts à l'emploi, les composants de Backbone.js fournissent un environnement intuitif que vous connaissez peut-être déjà lorsque vous travaillez avec des modèles et des vues sur le back-end. Les modèles et les collections dans Backbone.js sont simples, mais ils sont livrés avec des fonctionnalités très utiles, telles que la possibilité de les intégrer facilement aux API REST JSON. Mais ils sont également suffisamment flexibles pour être adaptés à presque toutes les utilisations pratiques.
Dans ce didacticiel Backbone.js, nous examinerons certaines erreurs courantes souvent commises par les développeurs indépendants qui tentent pour la première fois d'apprendre Backbone.js et les moyens de les éviter.
Erreur #1 : Ignorer l'arsenal des fonctionnalités de Backbone.js
Backbone.js est peut-être un framework minimaliste, mais il (avec Underscore.js) fournit une pléthore de caractéristiques et de fonctionnalités qui peuvent facilement couvrir les besoins les plus élémentaires et certains des besoins critiques qui surviennent lors du développement d'une application Web moderne. Une erreur courante que commettent souvent les développeurs débutants est qu'ils considèrent Backbone.js comme un autre framework client de type MVC pour le Web. Bien que cette section parle de quelque chose de très évident, en ce qui concerne Backbone.js, c'est une erreur vraiment critique de ne pas explorer le framework à fond. Le cadre peut être de petite taille, mais c'est ce qui en fait un excellent candidat pour cette exploration approfondie. Surtout son petit code source bien annoté.
Backbone.js fournit le strict minimum requis pour donner à votre application Web la structure dont elle peut bénéficier. Avec son extensibilité et sa pléthore de plugins, l'apprentissage de Backbone.js peut être utilisé pour créer des applications Web étonnantes. Certaines des fonctionnalités les plus évidentes de Backbone.js sont exposées à travers des modèles, des collections et des vues. Les composants de routeur et d'historique fournissent un mécanisme simple mais élégant pour prendre en charge le routage côté client. Bien que Underscore.js soit une dépendance de Backbone.js, il est assez bien intégré au framework, car les modèles et les collections bénéficient tous deux beaucoup de cette incroyable ceinture utilitaire pour JavaScript et sont également disponibles à votre disposition.
Le code source du framework est si bien écrit et annoté qu'on pourrait probablement tout lire en buvant une tasse de café. Les débutants peuvent tirer un grand profit de la lecture des annotations source, car ils peuvent en apprendre beaucoup sur le fonctionnement interne du framework, et également adopter un ensemble soigné de meilleures pratiques en matière de JavaScript.
Erreur #2 : Modifier le DOM en réponse directe à des événements arbitraires
Lorsque nous commençons à apprendre Backbone.js, nous avons tendance à ne pas faire les choses comme recommandé par Backbone.js. Par exemple, nous avons tendance à gérer les événements et à afficher les mises à jour comme nous le ferions avec jQuery sur des sites Web simples. Backbone.js est destiné à donner à votre application Web une structure rigide grâce à une séparation appropriée des préoccupations. Ce que nous avons souvent tendance à faire avec Backbone.js, c'est de mettre à jour une vue en réponse à des événements DOM arbitraires :
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function(event) { $(event.target).toggleClass('btn-play btn-pause') } }, // ... })
C'est quelque chose qu'il faut éviter à tout prix. Il peut être possible de trouver des exemples obscurs où cela peut avoir un sens; mais dans la plupart des cas, il existe de bien meilleures façons de le faire. En fait, une façon que je pourrais éventuellement illustrer ici est d'utiliser le modèle pour suivre l'état du lecteur audio et d'utiliser ces informations d'état pour rendre le bouton (ou plus précisément ses noms de classe):
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function(event) { this.model.set('playing', !this.model.get('playing')) } }, initialize: function() { this.listenTo(this.model, 'change', this.render) this.render() }, // ... })
<button class=”btn btn-<%- playing ? 'pause' : 'play' %>”></button>
Il peut y avoir de rares situations où la manipulation directe du DOM à partir des gestionnaires d'événements aura du sens, mais le coût impliqué par la gestion de manipulations complexes du DOM à partir des gestionnaires d'événements n'en vaut presque jamais la peine. C'est quelque chose que Backbone.js vise à résoudre. Utiliser Backbone.js pour faire quelque chose comme ça est une erreur.
Erreur #3 : sous-estimer le coût du rendu
Étant donné que Backbone.js facilite le rendu et le rendu du DOM à volonté ou en réponse à des événements, nous oublions souvent l'impact que cela a sur les performances globales de l'application Web. Il existe de nombreuses façons de finir par écraser la méthode de rendu sur nos vues. Souvent, cela peut sembler peu, car les navigateurs Web modernes deviennent des logiciels très performants. Mais à mesure que l'application Web se développe et que la quantité de données qu'elle traite augmente, la baisse des performances devient de plus en plus apparente.
Nous pouvons voir cela en action à travers un exemple artificiel où nous commençons avec une petite collection de modèles et le rendons dans une vue de liste :
var AudioPlayerPlaylist = Backbone.View.extend({ template: _.template('<ul> <% _.each(musics, function(m) { %> <li><%- m.title %></li> <% }) %> </ul>'), initialize: function() { this.listenTo(this.collection, 'add', this.render) }, // ... })
Dans cet exemple Backbone.js, nous effectuons un nouveau rendu chaque fois qu'un modèle est ajouté à la collection. Cela fonctionnera bien. Cependant, étant donné que l'événement "add" est déclenché chaque fois qu'un modèle est ajouté à la liste, imaginez que vous récupérez une grande liste de modèles sur le serveur. La méthode de rendu sera appelée plusieurs fois de suite, une fois pour chaque modèle dans la réponse du serveur. Un modèle suffisamment grand suffira à faire bégayer votre application et ruiner l'expérience utilisateur. Parfois, une petite réponse est suffisante, selon la complexité de la vue rendue.
Une solution très rapide consiste simplement à ne pas appeler la méthode de rendu pour chaque modèle ajouté. Dans de telles situations, les modèles seront ajoutés par lots et vous pouvez réellement faire quelque chose pour que la méthode de rendu ne se déclenche que lorsqu'elle est invoquée mais pas réinvoquée dans un laps de temps spécifié. La dépendance de Backbone.js Underscore.js est livrée avec une fonction utilitaire pratique pour cela : « _.debounce ». Tout ce dont vous avez besoin pour en profiter est de modifier la ligne JavaScript de liaison d'événement avec ceci :
this.listenTo(this.collection, 'add', _.debounce(_.bind(this.render), 128))
Cela entraînera le rappel d'événement à chaque fois que l'événement "add" se produira, cependant, il attendra 128 millisecondes à partir du dernier événement avant d'invoquer réellement la méthode de rendu.
Dans la plupart des cas, cela sera considéré comme une solution rapide. En fait, il existe des moyens plus appropriés d'éviter l'écrasement du rendu. Les développeurs derrière Trello ont écrit un article de blog sur leur expérience et leur approche pour améliorer les performances de rendu lors de l'utilisation de Backbone.js.
Erreur #4 : Laisser les auditeurs d'événements liés au-delà de leur utilisation
Laisser les écouteurs d'événements inutilisés liés est probablement quelque chose qui peut arriver quel que soit le framework JavaScript que vous utilisez, ou si vous en utilisez un du tout. Même si Backbone.js permet d'éviter facilement ce problème, c'est certainement une erreur de laisser encore des trous potentiels pour des fuites de mémoire faciles dans votre application Web. Le composant "Event" de Backbone.js est certainement une implémentation assez soignée. Il permet aux objets JavaScript d'implémenter facilement des fonctionnalités basées sur des événements. Étant donné que les vues sont l'endroit où la plupart de nos consommations d'événements se produisent généralement, il est facile de faire cette erreur :
var AudioPlayerControl = Backbone.View.extend({ initialize: function() { this.model.on('change', _.bind(this.render, this)) // ... }, // ... })
La ligne de liaison d'événement dans cet extrait de code n'est pas très différente de celle du premier exemple. Tout ce que nous avons fait ici, c'est que nous avons changé le "this.listenTo(this.model, ...)" en "this.model.on(…)". Étant donné que nous sommes très habitués à l'appel ".on()" pour la liaison d'événements d'après notre expérience avec d'autres frameworks et bibliothèques JavaScript, lorsque nous commençons à utiliser Backbone.js, nous avons souvent tendance à utiliser les appels ".on()" pour lier événements. Cela aurait été bien, seulement si nous avions pris la peine d'appeler ".off()" pour dissocier les gestionnaires d'événements lorsqu'ils ne sont plus nécessaires. Mais nous le faisons rarement, et cela finit par être une source de fuites de mémoire.

Backbone.js offre un moyen simple de résoudre ce problème. C'est grâce à l'utilisation de la méthode "object.listenTo()". Cela permet à l'objet que vous appelez "listenTo()" de garder une trace des événements qu'il écoute, et facilite également la dissociation de tous ces événements à la fois. Les vues, par exemple, arrêtent automatiquement d'écouter tous les événements liés dès que vous appelez "remove ()".
Erreur #5 : Créer des vues monolithiques
Si vous y réfléchissez, le minimalisme de Backbone.js offre une énorme flexibilité quant à la manière dont vous souhaitez concevoir le front-end de votre application Web. Les modèles, les collections et les vues étant les blocs de construction de vos composants, il est essentiel que vous les gardiez aussi légers et aussi spécifiques que possible. Le plus souvent, ce sont les vues qui finissent par devenir l'aspect le plus lourd de votre application Web en termes de code. Mais il est vraiment important que vous ne finissiez pas par créer des vues monolithiques géantes qui finissent par essayer de faire tout ce que votre application a à offrir. Au lieu de créer une vue géante "AudioPlayer" avec toute la logique entassée, divisez-la en plusieurs vues logiques telles qu'une vue pour la liste de lecture, une vue pour les commandes, une vue pour le visualiseur, etc. Le type de granularité que vous souhaitez garantir dépend probablement de l'application que vous essayez de créer.
En effet, avec des vues granulaires, où chaque vue fait quelque chose de spécifique et le fait correctement, développer une application Web avec Backbone.js devient un jeu d'enfant. Votre code devrait être plus maintenable et facile à étendre ou à modifier à l'avenir. Ensuite, il y a l'autre extrême, où vous finissez par en faire trop. Les vues Backbone.js sont conçues pour vous permettre de travailler facilement avec un modèle ou une collection, et cela peut probablement vous aider à structurer votre application. Ian Storm Taylor a partagé quelques idées précieuses sur son blog que vous devriez probablement garder à l'esprit lors de la mise en œuvre des vues.
Erreur #6 : ne pas réaliser que Backbone.js peut être adapté aux API non-RESTful
Backbone.js fonctionne avec les API RESTful basées sur JSON prêtes à l'emploi. Tout ce dont vous avez besoin pour cela est jQuery (ou quelque chose qui le remplace, comme Zepto). Cependant, Backbone.js est extrêmement extensible. En fait, Backbone.js peut être adapté pour utiliser d'autres types d'API et même d'autres types de formats d'encodage.
Le composant de Backbone.js qui traite de l'interaction du front-end avec les services back-end est "Sync". Ce composant expose un certain nombre d'attributs que vous pouvez facilement remplacer pour personnaliser la façon dont Backbone.js interagit avec les points de terminaison de l'API. En fait, il est également possible de remplacer le mécanisme de synchronisation par défaut par quelque chose qui n'est pas si traditionnel, c'est le moins qu'on puisse dire, comme l'utilisation de localStorage pour conserver les données, au lieu de services back-end.
Il existe de nombreux plugins qui facilitent la personnalisation du comportement de synchronisation de Backbone.js. Par exemple, un plugin appelé Backbone.dualStorage vous permet d'utiliser à la fois les services back-end et localStorage pour conserver les données. Lorsque votre application est hors ligne, le plug-in utilise localStorage pour continuer à traiter les demandes à partir des données mises en cache et suivre les modifications que vous pouvez synchroniser avec le serveur ultérieurement lorsque vous êtes en ligne.
Bien que l'utilisation de Backbone.js avec un back-end conçu pour être RESTful et compatible soit plus facile à utiliser, cela ne signifie pas que c'est tout ce avec quoi Backbone.js peut fonctionner. Avec quelques modifications apportées au mécanisme de synchronisation par défaut de Backbone.js, vous pouvez l'adapter à un large éventail d'API de service back-end et de formats d'encodage.
Il convient de mentionner que d'autres parties de Backbone.js sont également flexibles et facultatives. Par exemple, vous n'êtes pas obligé d'utiliser le moteur de modélisation par défaut fourni avec Underscore.js. Vous n'avez même pas besoin d'utiliser le composant de vue de Backbone.js et vous pouvez le remplacer par autre chose si vous le souhaitez.
Erreur #7 : Stocker des données sur des vues plutôt que dans des modèles
Une erreur que nous commettons souvent en tant que débutant en apprenant Backbone.js est de stocker les données directement sur les vues en tant qu'attributs. Ces données peuvent être là pour suivre un état ou une sélection de l'utilisateur. C'est quelque chose qui devrait être évité.
var AudioPlayerVisualizer = Backbone.View.extend({ events: { 'click .btn-color': function(event) { this.colorHex = $(event.target).data('color-hex') this.render() } }, // ... })
Vous pouvez toujours créer des modèles et des collections supplémentaires sans points de terminaison. Ceux-ci peuvent vous aider à stocker des données qui ne doivent pas nécessairement être conservées sur le back-end ou qui peuvent être de nature temporaire. Les stocker dans des modèles vous donne l'avantage de pouvoir écouter les changements. La vue pertinente, ou même plusieurs vues, peut observer ces modèles et se restituer si nécessaire.
Imaginez si vous stockiez réellement des variables de suivi d'état sur des vues et que vous deviez appeler la méthode de rendu chaque fois que vous les modifiiez. Manquer un seul appel à cette méthode de rendu pourrait laisser votre application dans un état cassé, en termes de ce que l'utilisateur vit à l'écran. De plus, avec de petites vues, vous devrez peut-être synchroniser ces variables d'état sur plusieurs objets de vue, puis appeler également la méthode de rendu sur eux.
Erreur #8 : Utiliser jQuery « .on() » au lieu d'événements délégués
Backbone.js a, à mon avis, une magnifique façon de gérer les événements DOM. Ne pas l'utiliser présente un tas d'inconvénients. La fonction de liaison d'événements ".on()" de jQuery peut sembler pratique, mais s'avère souvent compliquée à long terme. Par exemple, lorsque des éléments sont détachés du DOM, jQuery supprime automatiquement tous les gestionnaires d'événements liés aux éléments à l'aide de ".on ()". Cela signifie que tout événement DOM auquel vous essayez de vous lier depuis une vue devra être lié si vous détachez l'élément racine du DOM et le rattachez.
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function() { /* ... */ }, 'click .btn-prev': function() { /* ... */ }, 'click .btn-next': function() { /* ... */ }, 'click .btn-shuffle': function() { /* ... */ }, 'click .btn-repeat': function() { /* ... */ } }, // ... })
Lorsque l'élément correspondant à cette vue est rattaché au DOM, il suffit d'appeler "delegateEvents()" sur la vue pour lier tous ces événements.
Notez qu'il est important de comprendre comment ces événements sont liés. Au lieu de lier l'événement aux éléments spécifiés par le sélecteur, Backbone.js lie en fait le gestionnaire d'événements à l'élément racine de la vue. Cela fonctionne bien dans presque tous les cas et, en fait, fonctionne mieux pour la plupart de nos besoins. La modification ou le remplacement des éléments enfants dans la sous-arborescence DOM de la vue ne nécessite pas que Backbone.js lie à nouveau chaque événement sur les nouveaux éléments. Les écouteurs existants continuent de fonctionner.
Cependant, cela empêche certains événements d'être écoutés. Un exemple est l'endroit où vous pourriez vouloir écouter les événements de défilement sur "window" ou sur un élément défilable enfant. Dans le cas d'éléments enfants, vous pouvez créer une sous-vue pour cet élément et y gérer les événements.
Conclusion
Backbone.js, étant un framework très compact mais extensible, est un excellent choix pour les applications Web qui exigent une grande flexibilité en arrière-plan. Contrairement aux frameworks tels que Angular.js et Ember.js qui sont toujours là pour vous dire comment faire ce que vous voulez faire, Backbone.js prend du recul, vous donne un ensemble d'outils puissants et vous permet de décider comment utiliser leur. J'espère que ce didacticiel Backbone.js pour débutants vous aidera à éviter certaines des erreurs de développement courantes et à créer quelque chose d'incroyable avec.