Speeding Up Your Backbone Views with Document Fragments

Backbone is an incredibly lightweight framework for organizing complex JavaScript applications. One thing it’s really good at is keeping your data stored in memory rather than in the DOM. This greatly reduces the number of times you’ll need to query the DOM; a process which can be costly. In an age of so many Mobile visitors, performance costs like this can be detrimental to the success of your application.

While Backbone serves as a great tool to reduce DOM manipulation when it comes to data, it can add a great deal of reflow if your application is made of up many Backbone views and each view is injected into the DOM individually. Reflow is the web browser process for re-calculating the positions and geometries of elements in the DOM. This is an expensive process because it blocks all other processes in the browser. If your pages are made up of several Javascript templates, you’re likely injecting them each individually. Instead, append them to a document fragment and inject them all at once. Document fragments are a representation of a DOM node stored in memory. This gives you the ability to dynamically build out your DOM tree, attach events, and cache node references, all without needing to deal with the DOM itself. When built, you can inject everything all at once, rather than individually.

When building JavaScript applications, I’ll often have a hierarchy of JavaScript views. This helps keep my code organized and decoupled. Each view is responsible for instantiating and rendering child views. Instead of injecting each view into the DOM as we gather their HTML, the parent will wait to render to the DOM until all child views have been added to our document fragment.

jQuery makes this incredibly easy.

render: function() {
  // jQuery will handle creating a document fragment for us to work with
  $html = $( JST['template']( this.model.toJSON() ) ),
  // use jQuery to find an element within our document fragment to use as a child views element
  $child = $html.find('.child_placeholder'),
  // Instantiate a new view, and assign its element
  childView = new ChildView({ $el: $child });
  // Render a child view to our document fragment
  // Once all child views are rendered, inject it all into the DOM
  this.$el.html( $html );

Waiting until the end to inject our template into the DOM allows each child view to compile its own template and append itself to our document fragment. This is an incredibly fast and efficient way of breaking up your application into several manageable views, without adding additional work for the browser to reflow and repaint.

Ask a question or share this article, we’d love to hear from you!