2. XYZ – Best Practice Checklist for Single Page Applications
2
Contents
OBJECTIVE...................................................................................................................................................................3
PERFORMANCE TOOLS, RISKS, REMEDIES AND REWARDS..................................................................3
1) USING THE REQUIREJS OPTIMIZER...............................................................................................3
2) CREATING MEMORY LEAKS BY NOT UNBINDING EVENTS ...........................................................3
3) CAUSING MULTIPLE DOM REFLOWS WHEN RENDERING COLLECTIONS .................................4
4) DOING UNNECESSARY XHR REQUESTS ON PAGE LOAD..............................................................4
5) IDENTIFY PROBLEM AREAS USING CHROME TIMELINE ..........................................................5
6) REDUCING THE NUMBER OF VIEWS OR STASH THEM INTO ONE HTML?...............................5
7) FOLLOW BASIC JQUERY PERFORMANCE RULES...........................................................................5
8) BACKBONE BEST PRACTICES IN A PDF FILE.................................................................................6
REFERENCES..............................................................................................................................................................6
3. XYZ – Best Practice Checklist for Single Page Applications
3
Objective
This document will list out the various performance areas that can be handled for a web app
running a BackboneJS or any other using a MVC (MV*) based framework. The idea is to verify
and then utilize any of the techniques listed to enhance the code for better performance.
Performance tools, risks, remedies and rewards
1) Using the RequireJS Optimizer
https://blog.serverdensity.com/improving-frontend-web-performance-using-requirejs-optimiser/
Backbone handles our models, collections and views, jQuery handles our DOM interactions but
it’s RequireJS that glues it all together at an architectural level.
And even though RequireJS is great at minimizing requests and handling them asynchronously
they soon add up.
The RequireJS Optimiser is a tool that examines Require modules so that they can be
concatenated and minified. It means that developers can manage dependencies in a way that’s
familiar to them without incurring excess requests. The optimiser just becomes an additional
step before deployment.
Eg., In some projects node.js is used to run the requireJS optimizer over 2 separate build files
before deploying the application. One build file defines how to optimize the JavaScript, the
other defines how to optimise the stylesheets.
2) Creating memory leaks by not unbinding events
http://ozkatz.github.io/avoiding-common-backbonejs-pitfalls.html
Problems arise when we remove a view (usually by calling its .remove() method), but forgetting
to unbind the methods that listen on model changes. In such a case, even though the code may
no longer hold a reference to that view, it is never garbage collected since the model still holds
such a reference via the event handler.
The link above provides an insight with examples how to avoid this memory leak leading to
performance degrade.
Note: Some more examples of unbinding are provided at -
http://stackoverflow.com/questions/19148259/backbone-js-initialize-listeners-vs-events
---------------------------------------------------------------------------------------------------------------------------------
4. XYZ – Best Practice Checklist for Single Page Applications
4
3) Causing multiple DOM reflows when rendering collections
http://ozkatz.github.io/avoiding-common-backbonejs-pitfalls.html
Another common problem that is often visible with large collections is that on update or change,
we render a view for every single model in the collection. While this is sometimes necessary, it
can lead to severe performance issues and adversely affect UI responsiveness, especially on old
computers and mobile devices.
The reason for this is that every .append() we do in the render function causes the DOM to
reflow - meaning that the browser has to recalculate the position and size of every element in
the DOM tree. This is a relatively expensive operation, especially when multiplied by the amount
of models we have in our collection
The EXAMPLES on the link above provide examples on how to trigger only a single page reflow
by utilizing documentFragment.
Note: The steps and examples are stated at the link provided
---------------------------------------------------------------------------------------------------------------------------------
4) Doing unnecessary XHR requests on page load
http://ozkatz.github.io/avoiding-common-backbonejs-pitfalls.html
Backbone.js apps generally contain a single HTML page that initializes some basic structure and
loads a few js and css files to get the app up and running. Application data is retrieved using
Collections and Models, using their .fetch() methods.
While this is generally good practice, it has one noticeable disadvantage: when loading the page,
a user has to do at least one HTTP request to fetch our HTML page, and as soon as the app
loads, our .fetch() methods make a couple more HTTP calls to fetch data.
This can lead to noticeable load times on slow networks.
If we serve our HTML page using a server side template, we can simply embed the JSON data
needed to populate our initial models right in the page itself. It's not a pretty solution, but it
may help in many cases.
Note: The steps and examples are stated at the link provided
---------------------------------------------------------------------------------------------------------------------------------
5. XYZ – Best Practice Checklist for Single Page Applications
5
5) Identify Problem Areas USING Chrome Timeline
http://blog.pamelafox.org/2013/06/improving-backbone-app-performance.html
The link clearly states the usage of plain Chrome tools to identify the areas of concern and how
they can be mitigated to ensure better performance.
Note: Some more examples of unbinding are provided at -
http://www.smashingmagazine.com/2012/06/12/javascript-profiling-chrome-developer-tools/
---------------------------------------------------------------------------------------------------------------------------------
6) Reducing the number of Views or Stash them into one HTML?
http://stackoverflow.com/questions/11744634/lots-of-backbone-views-performance-issues
This link thrashes the debate raging as to whether we get a performance perk by reducing the
number of Views or just loading them upfront using caching.
7) Follow basic JQuery Performance rules
Examples are provided at - http://www.artzstudio.com/2009/04/jquery-performance-rules/
------------------------------------------------------------------------------------------------------------------------------------------
6. XYZ – Best Practice Checklist for Single Page Applications
6
8) Backbone best practices in a PDF file
Note: This link was copied from http://wayin.com/wp-content/uploads/2014/06/BackboneJS.pdf
-----------------------------------------------------------------------------------------------------------------------------------------
References
1. http://addyosmani.com/blog/taming-the-unicorn-easing-javascript-memory-profiling-in-devtools/
2. http://addyosmani.github.io/backbone-fundamentals/
3. http://andrewhenderson.me/tutorial/how-to-detect-backbone-memory-leaks/
4. http://blog.binarymist.net/2013/12/28/evaluation-of-angularjs-emberjs-backbonejs-marionettejs/
5. http://blog.pamelafox.org/2013/06/improving-backbone-app-performance.html
6. http://gent.ilcore.com/2011/08/finding-memory-leaks.html
7. http://gregfranko.com/blog/backbone-dot-js-convincing-the-boss-guide/
8. http://javascriptissexy.com/javascript-objects-in-detail/
9. http://javascriptissexy.com/learn-backbone-js-completely/
10. http://lostechies.com/derickbailey/2011/12/23/backbone-js-is-not-an-mvc-framework/
11. http://lostechies.com/derickbailey/2012/03/19/backbone-js-and-javascript-garbage-collection/
12. http://lostechies.com/derickbailey/2012/06/13/why-should-i-use-backbone-marionette-instead-of-
%E2%80%A6/
13. http://metametadata.wordpress.com/2013/06/17/backbone-js-1-0-0-nested-view-memory-leak/
14. http://msdn.microsoft.com/en-us/library/ms752347(v=vs.110).aspx
15. http://ozkatz.github.io/avoiding-common-backbonejs-pitfalls.html
16. http://stackoverflow.com/questions/11744634/lots-of-backbone-views-performance-issues
17. http://stackoverflow.com/questions/11774738/backbone-why-doesnt-a-collection-reset-trigger-a-
model-event?rq=1
18. http://stackoverflow.com/questions/14479176/how-to-get-javascript-objects-size-and-count-in-
browser-memory
19. http://stackoverflow.com/questions/15126334/backbone-js-memory-management-rising-dom-node-
count
20. http://stackoverflow.com/questions/15970525/how-to-find-js-memory-leaks
21. http://stackoverflow.com/questions/16738686/what-is-the-difference-between-extending-an-
object-using-prototype-or-inline
22. http://stackoverflow.com/questions/16843369/finding-an-infinite-or-very-large-loop-in-javascript-
using-chrome-dev-tools
23. http://stackoverflow.com/questions/19148259/backbone-js-initialize-listeners-vs-events
24. http://stackoverflow.com/questions/19621074/finding-javascript-memory-leaks-with-chrome
25. http://stackoverflow.com/questions/20816810/backbone-dispatch-listen-to-events-between-views