Create ein neues DocumentFragment, um alle Elemente vorzurendern, dann aktualisieren Sie das DOM einmal.
Auch zugunsten this.$(...)
über den globalen jQuery-Selektor $(...)
.
this.$
ist ein Proxy zu this.$el.find(...)
, die effizienter und weniger anfällig ist, etwas außerhalb der Ansicht zu wählen.
Die Verwendung der Kernfunktion von jQuery ($()
) in einer Ansicht kann fehlschlagen, wenn die Ansicht noch nicht gerendert wurde. Es ist also besser, immer durch this.$el
zu manipulieren, damit Sie Änderungen vornehmen können, bevor die Ansicht tatsächlich in das DOM eingefügt wird.
Behalten Sie alle Unteransichten, die in einem Array erstellt wurden, um sie später sauber zu entfernen.
initialize: function() {
this.childViews = [];
},
render: function() {
// cache the list jQuery object
this.$list = this.$("#item-table");
// Make sure to destroy every child view explicitely
// to avoid memory leaks
this.cleanup();
this.renderCollection();
return this;
},
Die eigentliche Optimierung beginnt hier mit einem temporären Container.
renderCollection: function() {
var container = document.createDocumentFragment();
this.collection.each(function(model) {
// this appends to a in memory document
container.appendChild(this.renderItem(model, false).el);
}, this);
// Update the DOM only once every child view was rendered.
this.$list.html(container);
return this;
},
Unsere renderItem
Funktion kann weiterhin verwendet werden, um ein einzelnes Element Ansicht zu machen und es sofort in den DOM setzen. Aber es bietet auch eine Option, um die DOM-Manipulation zu verschieben, und es gibt nur die Ansicht zurück.
renderItem: function(model, render) {
var view = new Item({ model: model });
this.childViews.push(view);
view.render();
if (render !== false) this.$list.append(view.el);
return view;
},
Um Speicherlecks mit baumelnden Hörer zu vermeiden, ist es wichtig, remove
auf jeder Ansicht aufrufen, bevor über sie zu vergessen.
Ich nutze eine zusätzliche Optimierung, indem ich den eigentlichen Anruf auf remove
verschiebe, damit wir keine Zeit verschwenden, während der Benutzer wartet.
Vielen Dank! Ich werde einen Benchmark für diese App im Vergleich zu React (virtuelles DOM) machen, und ich benutze diese Backbone-App als ein Beispiel für KVO (Schlüssel-Wert-Beobachtung) View-Model-Synchronisationsmechanismus. Ich möchte nur sicher sein - wenn ich diese Optimierungen implementiere, wird diese App immer noch ein gutes Beispiel für den KVO View-Model Synchronisationsmechanismus sein? – gfels
@gfels Es tut mir leid, ich bin nicht vertraut mit KVO View-Modell Synchronisationsmechanismus. Für den Vergleich von Backbone-Rendering mit React ist es irrelevant, da Backbone kein Rendering zur Verfügung stellt. Es bleibt dem Entwickler überlassen, was immer er möchte. Backbone bietet standardmäßig nur jQuery an, erlaubt dem Entwickler jedoch, das App-Rendering zu implementieren. –
@gfels Wenn Sie mit _KVO view-model syncing mechanism_ eine Zweiwege-Datenbindung meinen, dann bietet Backbone das auch nicht an, und es gibt Bibliotheken, die darauf spezialisiert sind und leicht mit Backbone verwendet werden können. (Epoxy, Knockout, Rückgrat.Stickit, sogar React könnte verwendet werden) –