Gli 8 errori più comuni commessi dagli sviluppatori di Backbone.js
Pubblicato: 2022-03-11Backbone.js è un framework minimalista che mira a fornire un semplice insieme di strutture di dati e funzionalità che è possibile utilizzare per creare il front-end di un'applicazione Web strutturata. I componenti di Backbone.js forniscono immediatamente un ambiente intuitivo con cui potresti già avere familiarità quando lavori con modelli e viste sul back-end. I modelli e le raccolte in Backbone.js sono semplici, ma sono dotati di alcune funzionalità molto utili, come l'opzione per integrarli facilmente con le API JSON REST. Ma sono anche abbastanza flessibili da essere adattati a quasi tutti gli usi pratici.
In questo tutorial di Backbone.js, daremo un'occhiata ad alcuni errori comuni che vengono spesso commessi dagli sviluppatori freelance che fanno il loro primo tentativo di apprendimento di Backbone.js e ai modi per evitarli.
Errore n. 1: ignorare l'arsenale delle funzionalità di Backbone.js
Backbone.js può essere un framework minimalista, ma (insieme a Underscore.js) fornisce una pletora di caratteristiche e funzionalità che possono facilmente coprire le esigenze più basilari e critiche che sorgono quando si sviluppa una moderna applicazione web. Un errore comune che gli sviluppatori principianti fanno spesso è che considerano Backbone.js un altro framework client simile a MVC per il Web. Sebbene questa sezione parli di qualcosa di molto ovvio, quando si tratta di Backbone.js è un errore davvero critico non esplorare a fondo il framework. Il framework può essere di piccole dimensioni, ma questo è ciò che lo rende un ottimo candidato per questa esplorazione approfondita. Soprattutto il suo codice sorgente piccolo e ben annotato.
Backbone.js fornisce il minimo indispensabile per dare alla tua applicazione web la struttura di cui può trarre vantaggio. Con la sua estensibilità e la pletora di plugin, l'apprendimento di Backbone.js può essere utilizzato per creare fantastiche applicazioni web. Alcune delle caratteristiche più ovvie di Backbone.js sono esposte attraverso modelli, raccolte e viste. I componenti del router e della cronologia forniscono un meccanismo semplice ma elegante per supportare il routing lato client. Sebbene Underscore.js sia una dipendenza di Backbone.js, è abbastanza ben integrato nel framework, poiché i modelli e le raccolte beneficiano entrambi molto di questa straordinaria cintura di utilità per JavaScript ed è anche disponibile a tua disposizione.
Il codice sorgente del framework è così ben scritto e annotato che probabilmente si potrebbe leggerlo tutto bevendo una tazza di caffè. I principianti possono trarre grandi benefici dalla lettura delle annotazioni di origine, in quanto possono imparare molto su come funziona internamente il framework e anche adottare una serie ordinata di migliori pratiche quando si tratta di JavaScript.
Errore n. 2: modificare il DOM in risposta diretta a eventi arbitrari
Qualcosa che tendiamo a fare quando iniziamo a imparare Backbone.js è non fare le cose come raccomandato da Backbone.js. Ad esempio, tendiamo a gestire gli eventi e visualizzare gli aggiornamenti come faremmo con jQuery su semplici siti Web. Backbone.js ha lo scopo di dare alla tua applicazione web una struttura rigida attraverso un'adeguata separazione delle preoccupazioni. Quello che spesso tendiamo a fare con Backbone.js è aggiornare una vista in risposta a eventi DOM arbitrari:
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function(event) { $(event.target).toggleClass('btn-play btn-pause') } }, // ... })
Questo è qualcosa che dovrebbe essere evitato a tutti i costi. Potrebbe essere possibile fornire esempi oscuri in cui ciò può avere senso; ma nella maggior parte dei casi, ci sono modi molto migliori per farlo. In effetti, un modo che potrei esemplificare qui è utilizzare il modello per tracciare lo stato del lettore audio e utilizzare le informazioni sullo stato per eseguire il rendering del pulsante (o più specificamente i suoi nomi di 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>
Potrebbero esserci rare situazioni in cui la manipolazione diretta del DOM dai gestori di eventi avrà senso, ma il costo necessario per la gestione di complesse manipolazioni DOM dai gestori di eventi non vale quasi mai la pena. Questo è qualcosa che Backbone.js mira a risolvere. Usare Backbone.js per fare qualcosa del genere è un errore.
Errore n. 3: sottovalutare il costo del rendering
Poiché Backbone.js rende molto semplice il rendering e il re-rendering del DOM a piacimento o in risposta a eventi, spesso trascuriamo l'impatto che ciò ha sulle prestazioni complessive dell'applicazione Web. Ci sono molti modi in cui possiamo finire per distruggere il metodo di rendering sulle nostre viste. Spesso questo potrebbe non sembrare molto, poiché i browser Web moderni stanno diventando software altamente performanti. Ma man mano che l'applicazione Web cresce e la quantità di dati con cui gestisce cresce, il calo delle prestazioni diventa sempre più evidente.
Possiamo vederlo in azione attraverso un esempio inventato in cui iniziamo con una piccola raccolta di modelli e lo trasformiamo in una vista elenco:
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) }, // ... })
In questo esempio di Backbone.js, stiamo rieseguendo il rendering ogni volta che un modello viene aggiunto alla raccolta. Questo funzionerà bene. Tuttavia, poiché l'evento "aggiungi" viene attivato ogni volta che un modello viene aggiunto all'elenco, immagina di recuperare un ampio elenco di modelli dal server. Il metodo di rendering verrà invocato più volte consecutivamente, una per ogni modello nella risposta dal server. Un modello sufficientemente grande sarà sufficiente per far balbettare la tua applicazione e rovinare l'esperienza dell'utente. A volte è sufficiente una piccola risposta, a seconda della complessità della vista che viene visualizzata.
Una soluzione molto rapida a questo è semplicemente non chiamare il metodo di rendering per ogni singolo modello che viene aggiunto. In situazioni come queste, i modelli verranno aggiunti in batch e puoi effettivamente fare qualcosa per attivare il metodo di rendering solo quando viene invocato ma non richiamato entro un determinato periodo di tempo. La dipendenza di Backbone.js Underscore.js viene fornita con una pratica funzione di utilità per questo: "_.debounce". Tutto ciò di cui hai bisogno per trarne vantaggio è modificare la riga JavaScript di associazione di eventi con questo:
this.listenTo(this.collection, 'add', _.debounce(_.bind(this.render), 128))
Ciò farà sì che il callback dell'evento venga attivato ogni volta che si verifica l'evento "add", tuttavia, attenderà 128 millisecondi dall'ultimo evento prima di invocare effettivamente il metodo di rendering.
Nella maggior parte dei casi, questa sarà considerata una soluzione simile a una soluzione rapida. In effetti, ci sono modi più appropriati per evitare il rendering thrashing. Gli sviluppatori dietro Trello una volta hanno scritto un post sul blog discutendo della loro esperienza e approccio per migliorare le prestazioni di rendering durante l'utilizzo di Backbone.js.
Errore n. 4: lasciare gli ascoltatori di eventi vincolati al loro utilizzo
Lasciare i listener di eventi inutilizzati vincolati è probabilmente qualcosa che può accadere indipendentemente dal framework JavaScript che usi o se ne usi uno. Anche se Backbone.js rende facile evitare questo problema, è certamente un errore lasciare ancora potenziali buchi per perdite di memoria facili nella tua applicazione web. Il componente "Event" di Backbone.js è sicuramente un'implementazione piuttosto ordinata. Consente agli oggetti JavaScript di implementare facilmente funzionalità basate su eventi. Poiché le visualizzazioni sono il luogo in cui di solito si verifica la maggior parte del consumo di eventi, è facile commettere questo errore lì:
var AudioPlayerControl = Backbone.View.extend({ initialize: function() { this.model.on('change', _.bind(this.render, this)) // ... }, // ... })
La riga di associazione dell'evento in questo frammento di codice non è molto diversa da quella del primo esempio. Tutto quello che abbiamo fatto qui è che abbiamo cambiato “this.listenTo(this.model, …)” in “this.model.on(…)”. Poiché siamo molto abituati alla chiamata ".on()" per l'associazione di eventi dalla nostra esperienza con altri framework e librerie JavaScript, quando iniziamo a utilizzare Backbone.js tendiamo spesso a utilizzare le chiamate ".on()" per eseguire il binding eventi. Questo sarebbe andato bene, solo se ci fossimo presi la briga di chiamare ".off()" per sbloccare i gestori di eventi quando non sono più necessari. Ma lo facciamo raramente e finisce per essere una fonte di perdite di memoria.

Backbone.js offre un modo semplice per risolvere questo problema. È attraverso l'uso del metodo "object.listenTo()". Ciò consente all'oggetto su cui stai chiamando "listenTo()" di tenere traccia di quali eventi sta ascoltando e semplifica anche la rimozione di tutti quegli eventi contemporaneamente. Le visualizzazioni, ad esempio, smettono automaticamente di ascoltare tutti gli eventi associati non appena si chiama "remove()" su di esso.
Errore n. 5: creare viste monolitiche
Se ci pensi, il minimalismo di Backbone.js offre un'enorme flessibilità su come vuoi architettare il front-end della tua applicazione web. Poiché i modelli, le raccolte e le viste sono gli elementi costitutivi dei componenti, è essenziale mantenerli il più leggeri e specifici possibile. Il più delle volte, sono le visualizzazioni che finiscono per diventare l'aspetto più pesante della tua applicazione web in termini di codice. Ma è davvero importante che tu non finisca per creare viste monolitiche giganti che finiscono per provare a fare tutto ciò che la tua applicazione ha da offrire. Invece di creare una gigantesca vista "AudioPlayer" con tutta la logica stipata al suo interno, suddividila in una serie di viste logiche come una vista per la playlist, una vista per i controlli, una vista per il visualizzatore e così via. Il tipo di granularità che vuoi garantire dipende probabilmente dall'applicazione che stai cercando di creare.
Questo perché con le viste granulari, in cui ogni vista fa qualcosa di specifico e lo fa bene, lo sviluppo di un'applicazione web con Backbone.js diventa un gioco da ragazzi. Il tuo codice dovrebbe essere più gestibile e facile da estendere o modificare in futuro. Poi c'è l'altro estremo, dove si finisce per esagerare. Le viste Backbone.js sono progettate per rendere conveniente lavorare con un modello o una raccolta e questo può probabilmente funzionare come suggerimento su come strutturare la tua applicazione. Ian Storm Taylor ha condiviso alcune idee preziose sul suo blog che probabilmente dovresti tenere a mente durante l'implementazione delle visualizzazioni.
Errore n. 6: non rendersi conto che Backbone.js può essere adattato ad API non RESTful
Backbone.js funziona con le API RESTful basate su JSON pronte all'uso. Tutto ciò di cui hai bisogno è jQuery (o qualcosa che possa sostituirlo, come Zepto). Tuttavia, Backbone.js è estremamente estensibile. Infatti, Backbone.js può essere adattato per utilizzare altri tipi di API e anche altri tipi di formati di codifica.
La componente di Backbone.js che si occupa dell'interazione del front-end con i servizi di back-end è “Sync”. Questo componente espone una serie di attributi che puoi facilmente sovrascrivere per personalizzare il modo in cui Backbone.js interagisce con gli endpoint API. In effetti, è anche possibile sostituire il meccanismo di sincronizzazione predefinito con qualcosa che non è così tradizionale per non dire altro, come l'utilizzo di localStorage per persistere i dati, invece dei servizi di back-end.
Esistono numerosi plugin che semplificano la personalizzazione del comportamento di sincronizzazione di Backbone.js. Ad esempio, un plug-in chiamato Backbone.dualStorage consente di utilizzare sia i servizi di back-end che localStorage per rendere persistenti i dati. Quando l'applicazione va offline, il plug-in utilizza localStorage per continuare a servire le richieste dai dati memorizzati nella cache e tenere traccia delle modifiche che potresti sincronizzare con il server in un secondo momento quando sei online.
Sebbene l'utilizzo di Backbone.js con un back-end progettato per essere RESTful ed essere compatibile con esso sia più facile da usare, non significa che tutto ciò con cui Backbone.js possa funzionare. Con alcune modifiche al meccanismo di sincronizzazione predefinito di Backbone.js, puoi adattarlo a un'ampia gamma di API di servizi back-end e formati di codifica.
Vale la pena ricordare che anche altre parti di Backbone.js sono flessibili e in modi opzionali. Ad esempio, non è necessario utilizzare il motore di creazione di modelli predefinito fornito con Underscore.js. Non devi nemmeno usare il componente di visualizzazione di Backbone.js e puoi sostituirlo con qualcos'altro se lo desideri.
Errore n. 7: memorizzare i dati nelle viste anziché nei modelli
Un errore che potremmo fare spesso come principianti che apprendono Backbone.js è archiviare i dati direttamente sulle viste come attributi. Questi dati potrebbero essere disponibili per tenere traccia di alcuni stati o di alcune selezioni dell'utente. Questo è qualcosa che dovrebbe essere evitato.
var AudioPlayerVisualizer = Backbone.View.extend({ events: { 'click .btn-color': function(event) { this.colorHex = $(event.target).data('color-hex') this.render() } }, // ... })
Puoi sempre creare alcuni modelli e raccolte aggiuntivi senza endpoint. Questi possono aiutarti a memorizzare i dati che non devono necessariamente essere mantenuti sul back-end o possono essere di natura temporanea. La loro memorizzazione nei modelli ti dà il vantaggio di poter ascoltare i cambiamenti. La vista pertinente, o anche più viste, può osservare questi modelli e renderli nuovamente se necessario.
Immagina di aver effettivamente memorizzato le variabili di tracciamento dello stato sulle viste e di dover chiamare il metodo di rendering ogni volta che le hai modificate. La mancanza di una sola chiamata a questo metodo di rendering potrebbe lasciare l'applicazione in uno stato interrotto, in termini di ciò che l'utente sta vivendo sullo schermo. Inoltre, con viste piccole potrebbe essere necessario sincronizzare queste variabili di stato su più oggetti vista e quindi dover chiamare anche il metodo di rendering su di essi.
Errore n. 8: utilizzo di jQuery ".on()" invece di eventi delegati
Backbone.js ha, secondo me, un modo magnifico di gestire gli eventi DOM. Non usarlo comporta una serie di svantaggi. La funzione di associazione di eventi ".on()" di jQuery può sembrare conveniente, ma spesso si rivela una seccatura a lungo termine. Ad esempio, quando gli elementi vengono scollegati dal DOM, jQuery elimina automaticamente tutti i gestori di eventi associati agli elementi utilizzando ".on()". Ciò significa che qualsiasi evento DOM a cui tenti di associarti dall'interno di una vista dovrà essere rebound se scolleghi l'elemento radice dal DOM e lo ricolleghi.
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() { /* ... */ } }, // ... })
Quando l'elemento corrispondente a questa vista viene ricollegato al DOM, tutto ciò che devi fare è chiamare "delegateEvents()" sulla vista per associare tutti questi eventi.
Nota che è importante capire come sono legati questi eventi. Invece di associare l'evento agli elementi specificati dal selettore, Backbone.js associa effettivamente il gestore dell'evento all'elemento radice della vista. Funziona bene in quasi tutti i casi e in effetti funziona meglio per la maggior parte delle nostre esigenze. La modifica o la sostituzione degli elementi figlio nel sottoalbero DOM della vista non richiede a Backbone.js di associare nuovamente ogni evento ai nuovi elementi. Gli ascoltatori esistenti continuano a funzionare.
Tuttavia, ciò impedisce l'ascolto di determinati eventi. Un esempio è dove potresti voler ascoltare gli eventi di scorrimento su "finestra" o su un elemento scorrevole figlio. In caso di elementi figlio, puoi creare una vista secondaria per quell'elemento e gestire gli eventi lì.
Conclusione
Backbone.js, essendo un framework molto compatto ma estensibile, è una scelta eccellente per le applicazioni web che richiedono una grande flessibilità dietro le quinte. A differenza di framework come Angular.js ed Ember.js che sono sempre disponibili per dirti come fare ciò che vuoi fare, Backbone.js fa un passo indietro, ti offre un potente set di strumenti e ti consente di decidere come utilizzare loro. Spero che questo tutorial di Backbone.js per principianti ti aiuti a evitare alcuni degli errori di sviluppo comuni e a costruire qualcosa di straordinario con esso.