SlideShare uma empresa Scribd logo
1 de 64
Baixar para ler offline
From Mess to Success,
Refactoring Large Applications with Backbone
dev.Objective()
May 14, 2015
Stacy London
@stacylondoner
McWay Falls, Julia Pfeiffer Burns State Park - Big Sur, CA - 2015 by Stacy London
About Me
I’ve been making things for the web since 1998.
Currently I’m a Senior Application Architect focused on
Front-End Engineering at Northwestern Mutual.
@stacylondoner
Northwestern Mutual
Northwestern Mutual has been helping families and businesses achieve
nancial security for nearly 160 years. Our nancial representatives build
relationships with clients through a distinctive planning approach that integrates
risk management with wealth accumulation, preservation and distribution. With
more than $230 billion in assets, $27 billion in revenues, nearly $90 billion in
assets under management and more than $1.5 trillion worth of life insurance
protection in force, Northwestern Mutual delivers nancial security to more than
4.3 million people who rely on us for insurance and investment
solutions, including life, disability and long-term care insurance; annuities; trust
services; mutual funds; and investment advisory products and services.
Northwestern Mutual is the marketing name for The Northwestern Mutual Life Insurance Company, Milwaukee, WI, and its
subsidiaries. Northwestern Mutual and its subsidiaries offer a comprehensive approach to nancial security solutions including: life
insurance, long-term care insurance, disability income insurance, annuities, investment products, and advisory products and
services. Subsidiaries include Northwestern Mutual Investment Services, LLC, broker-dealer, registered investment adviser,
member FINRA and SIPC; the Northwestern Mutual Wealth Management Company, limited purpose federal savings bank; and
Northwestern Long Term Care Insurance Company.
What do I mean by large application?
• a multi-page web application (MPA) built with ASP.NET
MVC
• 1500+ files | 343,000+ lines of code
• UI (CSS / JS)
• 230+ files | 42,000+ lines of code
Development Culture
• JEE/Java shop turned .NET/C#
• view JS as a bit of a “toy” language
• as JS was being added it was just being added without much
thought to maintainability, extensibility, testability, patterns,
etc.
• app was going to be heavy with JS yet initially on a platform
that wasn’t optimized for this kind of app dev.
• path of least resistance was to just put everything in 

$(document).ready()
https://www.youtube.com/watch?v=J---aiyznGQ
http://starecat.com/kermit-typing-on-a-typewriter-like-crazy-animation/
$(document).ready(function() {
});
http://www.wikihow.com/Make-a-Quick-Italian-Spaghetti
Problems
• one large JavaScript file in the <head> (all code included
on every page regardless if it needed it)
• all JavaScript global and in $(document).ready()
• some pages had inline JavaScript
• not commented
• no unit tests
• unclear if a function / event was used on multiple pages
Iterative Refactoring
• big codebase
• large team working on 2 week sprints that couldn’t be
slowed down
• refactors had to fit into a sprint
Refactor, Iteration 1: Break Apart JS
• figure out what JS belongs with each page and move
that JS into a separate le for that page
• include that JS with the partial HTML
Refactor, Iteration 1: Start Adding Unit Tests
• start adding unit tests for original code then make sure it
passed after refactoring as a safety/condence
mechanism
• to prepare for this journey of breaking code into smaller,
more testable chunks it was good to start early with
creating a test bed
• help make subsequent refactors less stressful
Refactor, Iteration 1: Start Adding Unit Tests
• picked Jasmine (BDD style) - http://
jasmine.github.io/
• a lot of the JS tied to DOM manipulation so not in
an ideal state for unit testing with Jasmine out of
the box
• needed DOM testing helper so added jquery-
jasmine library to add xtures (HTML snippets
to run tests against)
• no external UI Regression tools (e.g. Selenium) in a
state to do this validation throughout the refactor
Refactor, Iteration 2: Namespacing & Object Literal
• create an app namespace to get custom code out of the global
namespace (window) to avoid collisions with external libs/
frameworks
• introduce an Object Literal notation style in preparation for
Backbone (which uses this pattern)
• helps to organize the code and parameters logically

“an object containing a collection of key:value pairs with a colon
separating each pair of keys and values where keys can also
represent new namespaces”
• add closures with Instantly Invoked Function Expressions
(IIFEs)
https://gist.github.com/stacylondon
;
var myApp = myApp || {};
(function($, myApp) {
'use strict';
$.extend(myApp, {
init: function() {
this.commonStuff();
},
commonStuff: function() {
// common code across many or all pages
}
});
})(window.jQuery, window.myApp);
$(document).ready(function() {
myApp.init();
});
my-app.js
my-app.js
with comments
// prefix with semi-colon as safety net against concatenated
// scripts and/or other plugins that are not closed properly
;
// check for existence of myApp in the global namespace
var myApp = myApp || {};
// Use IIFE to:
// * encapsulate app logic to protect it from global namespace
// * pass in namespace so can be modified locally and isn't
// overwritten outside of our function context
// * ensure $ only refers to window.jQuery (defensive programming)
// * $ passed through as local var rather than as globals and this
// (slightly) quickens the resolution process and can be more
// efficiently minified (especially if regularly referenced)
(function($, myApp) {
my-app.js
with comments
(function($, myApp) {
// Strict mode makes several changes to normal JavaScript semantics:
// * eliminates some JS silent errors by changing them to throw errors.
// * fixes mistakes that make it difficult for JavaScript engines to
// perform optimizations: strict mode code can sometimes be made to
// run faster than identical code that's not strict mode. Add inside
// the IIFE so it's defined for just the functions defined within and
// doesn't flip concatenating/minified code to strict inadvertently
'use strict';
// extend the namespace with more functionality
$.extend(myApp, {
;
var myApp = myApp || {};
myApp.pageOne = myApp.pageOne || {};
(function($, myApp) {
'use strict';
$.extend(myApp.pageOne, {
init: function() {
this.pageSpecificStuff();
},
pageSpecificStuff: function() {
// code specific to this page
}
});
})(window.jQuery, window.myApp);
$(document).ready(function() {
myApp.pageOne.init();
});
page-one.js
Better but not great
• code is aligned with the screen to which is pertains
• pages now have mid-page script includes which isn’t
good for performance / rendering
• still hand-wiring Ajax calls
• entire-page-JS is not very modular
• want to break screens down into smaller features and
keep events neatly associated
Backbone to the rescue
• wanted something that provided/enforced structure but in a
lightweight way
• it’s a MPA not a SPA so full-featured SPA frameworks didn’t make
sense (e.g. Angular, Ember)
• wanted to be able to use just a small feature of the library/
framework and add more full integration over time (refactor in
multiple iterations)
• for these reasons Backbone.js made sense - http://backbonejs.org/
Refactor, Iteration 3: Page Level Backbone Views
• reducing boilerplate code
• views enforce organization of events
• views enforce an Object Literal notation pattern
• views helped developers think about encapsulating pieces of the
screen
• starting with just Views gave the team time to start planning for
refactoring back-end data provided by ASP.NET MVC Controllers
into more RESTful web services (Web API) which is necessary to
take full advantage of Backbone.js Models/Collections
Refactor, Iteration 3: Page Level Backbone Views
• my-app.js - is now responsible for instantiating the app
namespace and setting up a super light-weight view
manager for Backbone.js
• instantiate all available views on the page upon DOM
ready.
• page-one-view.js - no longer namespaced individually
since being added to the views object of the app
namespace
my-app.js
var myApp = myApp || {};
(function($, myApp) {
'use strict';
$.extend(myApp, {
init: function() {
this.initializeViews();
},
// view manager code
});
})(window.jQuery, window.myApp);
$(document).ready(function() {
myApp.init();
});
my-app.js
view manager
views: {},
initializeViews: function() {
for (var view in this.views) {
if (typeof this.views[view] === 'function') {
this.views[view.substring(0, 1).toLowerCase() +
view.substring(1, view.length)] = new this.views[view]();
}
}
},
addView: function(key, view) {
if (this.views.hasOwnProperty(key)) {
throw (new Error('A view with that key already exists.'));
}
this.views[key] = view;
},
getView: function(key) {
if (!this.views.hasOwnProperty(key)) {
throw new Error('View does not exist in views collection.');
}
return this.views[key];
}
page-one-view.js;
(function($, _, Backbone, myApp) {
'use strict';
var PageOneView = Backbone.View.extend({
el: '#pageOneMainContainer',
events: {
'click .something': 'doSomething'
},
initialize: function() {
this.setupValidation();
},
setupValidation: function() {
},
doSomething: function() {
}
});
myApp.addView('PageOneView', PageOneView);
}(window.jQuery, window._, window.Backbone, window.myApp));
Refactor, Iteration 4: Sub-Page Backbone Views
• start breaking the large page views into sub-page views
so that you can get truly modular
• share modules/code if a module exists on more than
one page
Refactor, Iteration 5: Backbone Models, Collections
• move code that is getting data and doing any business
logic out of the Views and into Models and Collections
• e.g. move phone number formatting out of View and
into the Model
• remove hand written Ajax, use BB API (e.g. fetch)
• make sure server side controllers were written in a
RESTful way
• still not complete across the application
var PageOneView = Backbone.View.extend({
el: '#pageOneMainContainer',
initialize: function() {
this.getSomeData();
},
getSomeData: function() {
var self = this;
$.ajax({
type: 'GET',
url: 'SomeEndpoint',
data: formData,
dataType: 'json',
success: function(data, textStatus, jqXHR) {
self.displayResults(data);
},
error: function(jqXHR, textStatus, errorThrown) {
self.displayError();
}
});
},
displayResults: function(data) {
},
displayError: function() {
}
});
Hand-wiring Ajax
Use Backbone.js API
to get data
// initialize view
var pageOneView = new PageOneView({
collection: new PageOneCollection([]),
});
var PageOneView = Backbone.View.extend({
el: '#pageOneMainContainer',
template: _.template($('#page-one-template').html()),
initialize: function() {},
render: function() {
this.$el.html(this.template({'collection': this.collection}));
// maintain chainability
return this;
}
});
var PageOneCollection = Backbone.Collection.extend({
initialize: function(models, options) {},
model: PageOneModel,
// RESTful web service URL
url: '/SomeEndpoint'
});
Refactor, Iteration 6: Mini-SPA
• treat each page of the multi-page app (MPA) like it’s a
miniature single page app (SPA)
• each page has a single entry point (main.js)
• this will setup the code for a module loader / build system
so that we can nally move the JS to the bottom of the
page and remove mid-page scripts
• improve performance (time to first paint - how long it
takes between a user entering a URL into the browser
and when he/she sees visual activity on screen)
Refactor, Iteration 7: Modules
• current version of JavaScript (ECMA-262) doesn’t provide a
way to import modules of code like more traditional
programming languages do
• modules are proposed for the next version of JS (ES6/
ES2015/Harmony)
• to use modules and manage dependencies with the current
version of JS you can use community driven methodologies
• there are two popular styles with associated script
loaders / build systems
Refactor, Iteration 7: Modules - AMD
• AMD - Asynchronous Module Definition



“The Asynchronous Module Definition (AMD) API
species a mechanism for dening modules such that the
module and its dependencies can be asynchronously
loaded. This is particularly well suited for the browser
environment where synchronous loading of modules
incurs performance, usability, debugging, and cross-
domain access problems.”

https://github.com/amdjs/amdjs-api/wiki/AMD
Refactor, Iteration 7: Modules - CommonJS
• CommonJS’s module format was made popular for
server-side JavaScript development (namely for Node.js/
NPM)
• it’s synchronous
• syntax is a bit easier as it frees you from the define()
wrapper that AMD enforces
• requires a build in a JS runtime
Refactor, Iteration 7: Modules - RequireJS
• popular script loader written by James Burke that helps you load
multiple script les and dene modules with or without
dependencies
• use RequireJS as first pass at module loading since async nature
means no build step during dev time (least disruption to the dev
team which is important because there is a learning curve)
• use almond (AMD API shim) so don’t have to add a special script
tag to load RequireJS and change any HTML
• this will move the code away from IIFEs to modules with
dependency management
my-app.js
// requireJS simplified commonJS wrapper
// do this so can use the commonJS style &
// make switch to browserify easier
define('app', function(require, exports, module) {
'use strict';
var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var Modernizr = require('modernizr');
var HeaderController = require('./header-controller');
var FooterController = require('./footer-controller');
var app = new Backbone.Application();
module.exports = app;
});
(function() {
var $ = require('jquery');
var app = require('app');
// dom ready
$(function() {
app.start();
});
}());
;
(function() {
'use strict';
var $ = require('jquery');
var PageOneController = require('./page-one-controller');
var app = require('app');
// dom ready
$(function() {
app.start({
ScreenController: PageOneController
});
});
}());
page-one-main.js
define('page-one-controller', function(require, exports, module) {
'use strict';
var Backbone = require('backbone');
var PageOneView = require('PageOneView');
var PageOneController = Backbone.Controller.extend({
initialize: function(options) {
var pageOneView = new PageOneView();
}
});
module.exports = PageOneController;
});
page-one-controller.js
define('page-one-view', function(require, exports, module) {
'use strict';
var Backbone = require('backbone');
var PageOneView = Backbone.View.extend({
});
module.exports = PageOneView;
});
page-one-view.js
Refactor, Iteration 7: Modules - Browserify
• Browserify lets you require('modules') in the browser by
bundling up all of your dependencies during a build step
• it’s the end-state module loader because it allows for easy
bundle splitting
• figure out common/shared JS and create a common
bundle then a bundle for the unique code on each page
• by having a main.js for each screen this will act as an
entry point so Browserify can nd all the modules
required and create a screen-specic bundle
Refactor, Iteration 7: Modules - Browserify
• means build during dev but we were already doing that
for our CSS with LESS
• “It’s great the dev community has
embraced compilation because it’s
inevitable.” - Brendan Eich at Fluent 2015
• the code will become very clean
'use strict';
var Backbone = require('backbone');
var PageOneView = Backbone.View.extend({
el: '#pageOneMainContainer',
initialize: function() {}
});
module.exports = PageOneView;
page-one-view.js
Summary
• the JavaScript is now modular and easier to maintain
• Backbone.js helps devs keep consistent with coding patterns and
organization (Object Literal notation, events)
• events are scoped to the smallest part of the page to which they matter
(Backbone.js)
• namespacing/IIFEs and then later module loader/build removes the
possibility of collisions with other frameworks/libs
• unit tests mean you can feel more confident to change things
• only sending JS to the browser that is necessary is good for
performance (think mobile)
http://ak-static.scoopon.com.au/scpn/deals/main/50000/50693_2.jpg
"The secret to building large apps is never
build large apps. Break your applications
into small pieces. Then, assemble those
testable, bite-sized pieces into your big
application"
- Justin Meyer, author JavaScriptMVC
Team Shout Out
• This was over the course of several years and I worked
with two other fantastic front-end engineers:
• Ryan Anklam ( @bittersweetryan )
• Zeek Chentnik ( http://ezekielchentnik.com )
JavaScript References
• “Patterns For Large-Scale JavaScript Application Architecture” by Addy
Osmani 

http://addyosmani.com/largescalejavascript/
• “Learning JavaScript Design Patterns” by Addy Osmani

http://addyosmani.com/resources/essentialjsdesignpatterns/book/
• “Using Objects to Organize Your Code” by Rebecca Murphey

http://rmurphey.com/blog/2009/10/15/using-objects-to-organize-your-code/
• “It’s time to start using JavaScript strict mode” by Nicholas Zakas

http://www.nczonline.net/blog/2012/03/13/its-time-to-start-using-javascript-strict-
mode/
• “Writing Modular JavaScript with AMD, CommonJS & ES Harmony” by Addy
Osmani

http://addyosmani.com/writing-modular-js/
Backbone.js References
• “Developing Backbone.js Applications” by Addy
Osmani

http://addyosmani.github.io/backbone-fundamentals/
• “Communicating Between Views in Client-Side
Apps” by Rebecca Murphey

http://bocoup.com/weblog/communicating-between-
views-in-client-side-apps/
• Talks from past Backbone Conferences are free/online:
http://backboneconf.com/

http://backboneconf.com/2013/
Thank You!
@stacylondoner
Code Samples:

https://gist.github.com/stacylondon

Mais conteĂşdo relacionado

Mais procurados

Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorialClaude Tech
 
Ember - introduction
Ember - introductionEmber - introduction
Ember - introductionHarikrishnan C
 
How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0Takuya Tejima
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricksJavier Eguiluz
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todaygerbille
 
AtlasCamp 2010: Making Confluence Macros Easy (for the user) - Dave Taylor
AtlasCamp 2010: Making Confluence Macros Easy (for the user) - Dave TaylorAtlasCamp 2010: Making Confluence Macros Easy (for the user) - Dave Taylor
AtlasCamp 2010: Making Confluence Macros Easy (for the user) - Dave TaylorAtlassian
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSAntonio Peric-Mazar
 
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...Atlassian
 
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...Atlassian
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackIgnacio MartĂ­n
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async PatternsTrevorBurnham
 
WebcampZG - Rails 4
WebcampZG - Rails 4WebcampZG - Rails 4
WebcampZG - Rails 4shnikola
 
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...Caldera Labs
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"GeeksLab Odessa
 
Promises are so passĂŠ - Tim Perry - Codemotion Milan 2016
Promises are so passĂŠ - Tim Perry - Codemotion Milan 2016Promises are so passĂŠ - Tim Perry - Codemotion Milan 2016
Promises are so passĂŠ - Tim Perry - Codemotion Milan 2016Codemotion
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceParashuram N
 
How to React Native
How to React NativeHow to React Native
How to React NativeDmitry Ulyanov
 
Building and deploying React applications
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applicationsAstrails
 
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - AppenginePython Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - AppenginePython Ireland
 

Mais procurados (20)

Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorial
 
Ember - introduction
Ember - introductionEmber - introduction
Ember - introduction
 
How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricks
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of today
 
AtlasCamp 2010: Making Confluence Macros Easy (for the user) - Dave Taylor
AtlasCamp 2010: Making Confluence Macros Easy (for the user) - Dave TaylorAtlasCamp 2010: Making Confluence Macros Easy (for the user) - Dave Taylor
AtlasCamp 2010: Making Confluence Macros Easy (for the user) - Dave Taylor
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJS
 
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
 
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
WebcampZG - Rails 4
WebcampZG - Rails 4WebcampZG - Rails 4
WebcampZG - Rails 4
 
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
 
Angular js
Angular jsAngular js
Angular js
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"
 
Promises are so passĂŠ - Tim Perry - Codemotion Milan 2016
Promises are so passĂŠ - Tim Perry - Codemotion Milan 2016Promises are so passĂŠ - Tim Perry - Codemotion Milan 2016
Promises are so passĂŠ - Tim Perry - Codemotion Milan 2016
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 
How to React Native
How to React NativeHow to React Native
How to React Native
 
Building and deploying React applications
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applications
 
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - AppenginePython Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
 

Destaque

170209 apm shipley capability briefing-esp v073-cliente
170209 apm shipley capability briefing-esp v073-cliente170209 apm shipley capability briefing-esp v073-cliente
170209 apm shipley capability briefing-esp v073-clienteAPM-Shipley
 
Interesting Concept Yachts
Interesting Concept YachtsInteresting Concept Yachts
Interesting Concept YachtsCal Staggers
 
chuyên làm clip quảng cáo tốt giá rẻ
chuyên làm clip quảng cáo tốt giá rẻchuyên làm clip quảng cáo tốt giá rẻ
chuyên làm clip quảng cáo tốt giá rẻyon214
 
Sụn khớp hư tổn làm khớp mau thoái hóa
Sụn khớp hư tổn làm khớp mau thoái hóaSụn khớp hư tổn làm khớp mau thoái hóa
Sụn khớp hư tổn làm khớp mau thoái hóanona479
 
Storie comuni
Storie comuniStorie comuni
Storie comuniframanini
 
Er Din Evne til at Kobe Kosttilskud, Naturlaegemidler, og Tonics i Fare i USAh
Er Din Evne til at Kobe Kosttilskud, Naturlaegemidler, og Tonics i Fare i USAhEr Din Evne til at Kobe Kosttilskud, Naturlaegemidler, og Tonics i Fare i USAh
Er Din Evne til at Kobe Kosttilskud, Naturlaegemidler, og Tonics i Fare i USAhgruesomeocclusi00
 
Untitled Presentation
Untitled PresentationUntitled Presentation
Untitled PresentationIgnacio Rippa
 
7 Managed services
7 Managed services7 Managed services
7 Managed servicesDarren Moore
 
Referral specialist performance appraisal
Referral specialist performance appraisalReferral specialist performance appraisal
Referral specialist performance appraisalcodyfred747
 
Meaningful EMR Use - A Survey of Family Practice Clinics - TAGG_BEKKI_MSC_2015
Meaningful EMR Use - A Survey of Family Practice Clinics - TAGG_BEKKI_MSC_2015Meaningful EMR Use - A Survey of Family Practice Clinics - TAGG_BEKKI_MSC_2015
Meaningful EMR Use - A Survey of Family Practice Clinics - TAGG_BEKKI_MSC_2015Bekki Tagg
 
الموازنة العامة
الموازنة العامةالموازنة العامة
الموازنة العامةNour Elbader
 
Thai Hoa Dot Song Co
Thai Hoa Dot Song CoThai Hoa Dot Song Co
Thai Hoa Dot Song Cotracy414
 
Future comms - the last will and testament of #ukhousing
Future comms - the last will and testament of #ukhousingFuture comms - the last will and testament of #ukhousing
Future comms - the last will and testament of #ukhousingBromford Lab
 

Destaque (20)

170209 apm shipley capability briefing-esp v073-cliente
170209 apm shipley capability briefing-esp v073-cliente170209 apm shipley capability briefing-esp v073-cliente
170209 apm shipley capability briefing-esp v073-cliente
 
Interesting Concept Yachts
Interesting Concept YachtsInteresting Concept Yachts
Interesting Concept Yachts
 
sadia'CV
sadia'CVsadia'CV
sadia'CV
 
chuyên làm clip quảng cáo tốt giá rẻ
chuyên làm clip quảng cáo tốt giá rẻchuyên làm clip quảng cáo tốt giá rẻ
chuyên làm clip quảng cáo tốt giá rẻ
 
Sụn khớp hư tổn làm khớp mau thoái hóa
Sụn khớp hư tổn làm khớp mau thoái hóaSụn khớp hư tổn làm khớp mau thoái hóa
Sụn khớp hư tổn làm khớp mau thoái hóa
 
Storie comuni
Storie comuniStorie comuni
Storie comuni
 
Er Din Evne til at Kobe Kosttilskud, Naturlaegemidler, og Tonics i Fare i USAh
Er Din Evne til at Kobe Kosttilskud, Naturlaegemidler, og Tonics i Fare i USAhEr Din Evne til at Kobe Kosttilskud, Naturlaegemidler, og Tonics i Fare i USAh
Er Din Evne til at Kobe Kosttilskud, Naturlaegemidler, og Tonics i Fare i USAh
 
IH Poster Samples
IH Poster SamplesIH Poster Samples
IH Poster Samples
 
Untitled Presentation
Untitled PresentationUntitled Presentation
Untitled Presentation
 
Portfolio
PortfolioPortfolio
Portfolio
 
7 Managed services
7 Managed services7 Managed services
7 Managed services
 
Referral specialist performance appraisal
Referral specialist performance appraisalReferral specialist performance appraisal
Referral specialist performance appraisal
 
Feedback
FeedbackFeedback
Feedback
 
Meaningful EMR Use - A Survey of Family Practice Clinics - TAGG_BEKKI_MSC_2015
Meaningful EMR Use - A Survey of Family Practice Clinics - TAGG_BEKKI_MSC_2015Meaningful EMR Use - A Survey of Family Practice Clinics - TAGG_BEKKI_MSC_2015
Meaningful EMR Use - A Survey of Family Practice Clinics - TAGG_BEKKI_MSC_2015
 
الموازنة العامة
الموازنة العامةالموازنة العامة
الموازنة العامة
 
ARTE UNICO LOOKBOOK
ARTE UNICO LOOKBOOKARTE UNICO LOOKBOOK
ARTE UNICO LOOKBOOK
 
Thai Hoa Dot Song Co
Thai Hoa Dot Song CoThai Hoa Dot Song Co
Thai Hoa Dot Song Co
 
Future comms - the last will and testament of #ukhousing
Future comms - the last will and testament of #ukhousingFuture comms - the last will and testament of #ukhousing
Future comms - the last will and testament of #ukhousing
 
Sivakumar Resume
Sivakumar ResumeSivakumar Resume
Sivakumar Resume
 
My five minutes bell
My five minutes bellMy five minutes bell
My five minutes bell
 

Semelhante a Refactoring Large Web Applications with Backbone.js

Rp 6 session 2 naresh bhatia
Rp 6  session 2 naresh bhatiaRp 6  session 2 naresh bhatia
Rp 6 session 2 naresh bhatiasapientindia
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Againjonknapp
 
Os Haase
Os HaaseOs Haase
Os Haaseoscon2007
 
React Basic and Advance || React Basic
React Basic and Advance   || React BasicReact Basic and Advance   || React Basic
React Basic and Advance || React Basicrafaqathussainc077
 
Play Support in Cloud Foundry
Play Support in Cloud FoundryPlay Support in Cloud Foundry
Play Support in Cloud Foundryrajdeep
 
Building Isomorphic Apps (JSConf.Asia 2014)
Building Isomorphic Apps (JSConf.Asia 2014)Building Isomorphic Apps (JSConf.Asia 2014)
Building Isomorphic Apps (JSConf.Asia 2014)Spike Brehm
 
Google app engine by example
Google app engine by exampleGoogle app engine by example
Google app engine by exampleAlexander Zamkovyi
 
Android Workshop
Android WorkshopAndroid Workshop
Android WorkshopJunda Ong
 
Code Generation in Magento 2
Code Generation in Magento 2Code Generation in Magento 2
Code Generation in Magento 2Sergii Shymko
 
Advanced Web Development
Advanced Web DevelopmentAdvanced Web Development
Advanced Web DevelopmentRobert J. Stein
 
Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]GDSC UofT Mississauga
 
Developing large scale JavaScript applications
Developing large scale JavaScript applicationsDeveloping large scale JavaScript applications
Developing large scale JavaScript applicationsMilan Korsos
 
Mean stack Magics
Mean stack MagicsMean stack Magics
Mean stack MagicsAishura Aishu
 
Html5 and beyond the next generation of mobile web applications - Touch Tou...
Html5 and beyond   the next generation of mobile web applications - Touch Tou...Html5 and beyond   the next generation of mobile web applications - Touch Tou...
Html5 and beyond the next generation of mobile web applications - Touch Tou...RIA RUI Society
 
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web ToolkitJava Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web ToolkitIMC Institute
 
Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Matt Raible
 
jQuery Mobile and JavaScript
jQuery Mobile and JavaScriptjQuery Mobile and JavaScript
jQuery Mobile and JavaScriptGary Yeh
 
Advanced #6 clean architecture
Advanced #6  clean architectureAdvanced #6  clean architecture
Advanced #6 clean architectureVitali Pekelis
 

Semelhante a Refactoring Large Web Applications with Backbone.js (20)

Rp 6 session 2 naresh bhatia
Rp 6  session 2 naresh bhatiaRp 6  session 2 naresh bhatia
Rp 6 session 2 naresh bhatia
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Again
 
Os Haase
Os HaaseOs Haase
Os Haase
 
React Basic and Advance || React Basic
React Basic and Advance   || React BasicReact Basic and Advance   || React Basic
React Basic and Advance || React Basic
 
Play Support in Cloud Foundry
Play Support in Cloud FoundryPlay Support in Cloud Foundry
Play Support in Cloud Foundry
 
Building Isomorphic Apps (JSConf.Asia 2014)
Building Isomorphic Apps (JSConf.Asia 2014)Building Isomorphic Apps (JSConf.Asia 2014)
Building Isomorphic Apps (JSConf.Asia 2014)
 
Google app engine by example
Google app engine by exampleGoogle app engine by example
Google app engine by example
 
Android Workshop
Android WorkshopAndroid Workshop
Android Workshop
 
Code Generation in Magento 2
Code Generation in Magento 2Code Generation in Magento 2
Code Generation in Magento 2
 
Advanced Web Development
Advanced Web DevelopmentAdvanced Web Development
Advanced Web Development
 
Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]
 
Developing large scale JavaScript applications
Developing large scale JavaScript applicationsDeveloping large scale JavaScript applications
Developing large scale JavaScript applications
 
Mean stack Magics
Mean stack MagicsMean stack Magics
Mean stack Magics
 
Html5 and beyond the next generation of mobile web applications - Touch Tou...
Html5 and beyond   the next generation of mobile web applications - Touch Tou...Html5 and beyond   the next generation of mobile web applications - Touch Tou...
Html5 and beyond the next generation of mobile web applications - Touch Tou...
 
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web ToolkitJava Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
 
Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017
 
Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web Toolkit
 
jQuery Mobile and JavaScript
jQuery Mobile and JavaScriptjQuery Mobile and JavaScript
jQuery Mobile and JavaScript
 
Advanced #6 clean architecture
Advanced #6  clean architectureAdvanced #6  clean architecture
Advanced #6 clean architecture
 

Último

Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa494f574xmv
 
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一Fs
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhimiss dipika
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxDyna Gilbert
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一z xss
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Sonam Pathan
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Lucknow
 
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一Fs
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Dana Luther
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationLinaWolf1
 
Magic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMagic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMartaLoveguard
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Paul Calvano
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作ys8omjxb
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Sonam Pathan
 
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)Christopher H Felton
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Excelmac1
 

Último (20)

Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa
 
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
 
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhi
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptx
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
 
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 Documentation
 
Magic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMagic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptx
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24
 
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170
 
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
 
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
 
Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...
 

Refactoring Large Web Applications with Backbone.js

  • 1. From Mess to Success, Refactoring Large Applications with Backbone dev.Objective() May 14, 2015 Stacy London @stacylondoner McWay Falls, Julia Pfeiffer Burns State Park - Big Sur, CA - 2015 by Stacy London
  • 2. About Me I’ve been making things for the web since 1998. Currently I’m a Senior Application Architect focused on Front-End Engineering at Northwestern Mutual. @stacylondoner
  • 3. Northwestern Mutual Northwestern Mutual has been helping families and businesses achieve nancial security for nearly 160 years. Our nancial representatives build relationships with clients through a distinctive planning approach that integrates risk management with wealth accumulation, preservation and distribution. With more than $230 billion in assets, $27 billion in revenues, nearly $90 billion in assets under management and more than $1.5 trillion worth of life insurance protection in force, Northwestern Mutual delivers nancial security to more than 4.3 million people who rely on us for insurance and investment solutions, including life, disability and long-term care insurance; annuities; trust services; mutual funds; and investment advisory products and services. Northwestern Mutual is the marketing name for The Northwestern Mutual Life Insurance Company, Milwaukee, WI, and its subsidiaries. Northwestern Mutual and its subsidiaries offer a comprehensive approach to nancial security solutions including: life insurance, long-term care insurance, disability income insurance, annuities, investment products, and advisory products and services. Subsidiaries include Northwestern Mutual Investment Services, LLC, broker-dealer, registered investment adviser, member FINRA and SIPC; the Northwestern Mutual Wealth Management Company, limited purpose federal savings bank; and Northwestern Long Term Care Insurance Company.
  • 4. What do I mean by large application? • a multi-page web application (MPA) built with ASP.NET MVC • 1500+ les | 343,000+ lines of code • UI (CSS / JS) • 230+ les | 42,000+ lines of code
  • 5. Development Culture • JEE/Java shop turned .NET/C# • view JS as a bit of a “toy” language • as JS was being added it was just being added without much thought to maintainability, extensibility, testability, patterns, etc. • app was going to be heavy with JS yet initially on a platform that wasn’t optimized for this kind of app dev. • path of least resistance was to just put everything in 
 $(document).ready()
  • 9. Problems • one large JavaScript le in the <head> (all code included on every page regardless if it needed it) • all JavaScript global and in $(document).ready() • some pages had inline JavaScript • not commented • no unit tests • unclear if a function / event was used on multiple pages
  • 10. Iterative Refactoring • big codebase • large team working on 2 week sprints that couldn’t be slowed down • refactors had to t into a sprint
  • 11.
  • 12.
  • 13. Refactor, Iteration 1: Break Apart JS • gure out what JS belongs with each page and move that JS into a separate le for that page • include that JS with the partial HTML
  • 14. Refactor, Iteration 1: Start Adding Unit Tests • start adding unit tests for original code then make sure it passed after refactoring as a safety/condence mechanism • to prepare for this journey of breaking code into smaller, more testable chunks it was good to start early with creating a test bed • help make subsequent refactors less stressful
  • 15. Refactor, Iteration 1: Start Adding Unit Tests • picked Jasmine (BDD style) - http:// jasmine.github.io/ • a lot of the JS tied to DOM manipulation so not in an ideal state for unit testing with Jasmine out of the box • needed DOM testing helper so added jquery- jasmine library to add xtures (HTML snippets to run tests against) • no external UI Regression tools (e.g. Selenium) in a state to do this validation throughout the refactor
  • 16.
  • 17.
  • 18. Refactor, Iteration 2: Namespacing & Object Literal • create an app namespace to get custom code out of the global namespace (window) to avoid collisions with external libs/ frameworks • introduce an Object Literal notation style in preparation for Backbone (which uses this pattern) • helps to organize the code and parameters logically
 “an object containing a collection of key:value pairs with a colon separating each pair of keys and values where keys can also represent new namespaces” • add closures with Instantly Invoked Function Expressions (IIFEs)
  • 20. ; var myApp = myApp || {}; (function($, myApp) { 'use strict'; $.extend(myApp, { init: function() { this.commonStuff(); }, commonStuff: function() { // common code across many or all pages } }); })(window.jQuery, window.myApp); $(document).ready(function() { myApp.init(); }); my-app.js
  • 21. my-app.js with comments // prefix with semi-colon as safety net against concatenated // scripts and/or other plugins that are not closed properly ; // check for existence of myApp in the global namespace var myApp = myApp || {}; // Use IIFE to: // * encapsulate app logic to protect it from global namespace // * pass in namespace so can be modified locally and isn't // overwritten outside of our function context // * ensure $ only refers to window.jQuery (defensive programming) // * $ passed through as local var rather than as globals and this // (slightly) quickens the resolution process and can be more // efficiently minified (especially if regularly referenced) (function($, myApp) {
  • 22. my-app.js with comments (function($, myApp) { // Strict mode makes several changes to normal JavaScript semantics: // * eliminates some JS silent errors by changing them to throw errors. // * fixes mistakes that make it difficult for JavaScript engines to // perform optimizations: strict mode code can sometimes be made to // run faster than identical code that's not strict mode. Add inside // the IIFE so it's defined for just the functions defined within and // doesn't flip concatenating/minified code to strict inadvertently 'use strict'; // extend the namespace with more functionality $.extend(myApp, {
  • 23. ; var myApp = myApp || {}; myApp.pageOne = myApp.pageOne || {}; (function($, myApp) { 'use strict'; $.extend(myApp.pageOne, { init: function() { this.pageSpecificStuff(); }, pageSpecificStuff: function() { // code specific to this page } }); })(window.jQuery, window.myApp); $(document).ready(function() { myApp.pageOne.init(); }); page-one.js
  • 24. Better but not great • code is aligned with the screen to which is pertains • pages now have mid-page script includes which isn’t good for performance / rendering • still hand-wiring Ajax calls • entire-page-JS is not very modular • want to break screens down into smaller features and keep events neatly associated
  • 25. Backbone to the rescue • wanted something that provided/enforced structure but in a lightweight way • it’s a MPA not a SPA so full-featured SPA frameworks didn’t make sense (e.g. Angular, Ember) • wanted to be able to use just a small feature of the library/ framework and add more full integration over time (refactor in multiple iterations) • for these reasons Backbone.js made sense - http://backbonejs.org/
  • 26.
  • 27. Refactor, Iteration 3: Page Level Backbone Views • reducing boilerplate code • views enforce organization of events • views enforce an Object Literal notation pattern • views helped developers think about encapsulating pieces of the screen • starting with just Views gave the team time to start planning for refactoring back-end data provided by ASP.NET MVC Controllers into more RESTful web services (Web API) which is necessary to take full advantage of Backbone.js Models/Collections
  • 28. Refactor, Iteration 3: Page Level Backbone Views • my-app.js - is now responsible for instantiating the app namespace and setting up a super light-weight view manager for Backbone.js • instantiate all available views on the page upon DOM ready. • page-one-view.js - no longer namespaced individually since being added to the views object of the app namespace
  • 29.
  • 30. my-app.js var myApp = myApp || {}; (function($, myApp) { 'use strict'; $.extend(myApp, { init: function() { this.initializeViews(); }, // view manager code }); })(window.jQuery, window.myApp); $(document).ready(function() { myApp.init(); });
  • 31. my-app.js view manager views: {}, initializeViews: function() { for (var view in this.views) { if (typeof this.views[view] === 'function') { this.views[view.substring(0, 1).toLowerCase() + view.substring(1, view.length)] = new this.views[view](); } } }, addView: function(key, view) { if (this.views.hasOwnProperty(key)) { throw (new Error('A view with that key already exists.')); } this.views[key] = view; }, getView: function(key) { if (!this.views.hasOwnProperty(key)) { throw new Error('View does not exist in views collection.'); } return this.views[key]; }
  • 32. page-one-view.js; (function($, _, Backbone, myApp) { 'use strict'; var PageOneView = Backbone.View.extend({ el: '#pageOneMainContainer', events: { 'click .something': 'doSomething' }, initialize: function() { this.setupValidation(); }, setupValidation: function() { }, doSomething: function() { } }); myApp.addView('PageOneView', PageOneView); }(window.jQuery, window._, window.Backbone, window.myApp));
  • 33.
  • 34. Refactor, Iteration 4: Sub-Page Backbone Views • start breaking the large page views into sub-page views so that you can get truly modular • share modules/code if a module exists on more than one page
  • 35.
  • 36.
  • 37. Refactor, Iteration 5: Backbone Models, Collections • move code that is getting data and doing any business logic out of the Views and into Models and Collections • e.g. move phone number formatting out of View and into the Model • remove hand written Ajax, use BB API (e.g. fetch) • make sure server side controllers were written in a RESTful way • still not complete across the application
  • 38.
  • 39. var PageOneView = Backbone.View.extend({ el: '#pageOneMainContainer', initialize: function() { this.getSomeData(); }, getSomeData: function() { var self = this; $.ajax({ type: 'GET', url: 'SomeEndpoint', data: formData, dataType: 'json', success: function(data, textStatus, jqXHR) { self.displayResults(data); }, error: function(jqXHR, textStatus, errorThrown) { self.displayError(); } }); }, displayResults: function(data) { }, displayError: function() { } }); Hand-wiring Ajax
  • 40. Use Backbone.js API to get data // initialize view var pageOneView = new PageOneView({ collection: new PageOneCollection([]), }); var PageOneView = Backbone.View.extend({ el: '#pageOneMainContainer', template: _.template($('#page-one-template').html()), initialize: function() {}, render: function() { this.$el.html(this.template({'collection': this.collection})); // maintain chainability return this; } }); var PageOneCollection = Backbone.Collection.extend({ initialize: function(models, options) {}, model: PageOneModel, // RESTful web service URL url: '/SomeEndpoint' });
  • 41.
  • 42. Refactor, Iteration 6: Mini-SPA • treat each page of the multi-page app (MPA) like it’s a miniature single page app (SPA) • each page has a single entry point (main.js) • this will setup the code for a module loader / build system so that we can nally move the JS to the bottom of the page and remove mid-page scripts • improve performance (time to rst paint - how long it takes between a user entering a URL into the browser and when he/she sees visual activity on screen)
  • 43.
  • 44.
  • 45.
  • 46. Refactor, Iteration 7: Modules • current version of JavaScript (ECMA-262) doesn’t provide a way to import modules of code like more traditional programming languages do • modules are proposed for the next version of JS (ES6/ ES2015/Harmony) • to use modules and manage dependencies with the current version of JS you can use community driven methodologies • there are two popular styles with associated script loaders / build systems
  • 47.
  • 48. Refactor, Iteration 7: Modules - AMD • AMD - Asynchronous Module Denition
 
 “The Asynchronous Module Denition (AMD) API species a mechanism for dening modules such that the module and its dependencies can be asynchronously loaded. This is particularly well suited for the browser environment where synchronous loading of modules incurs performance, usability, debugging, and cross- domain access problems.”
 https://github.com/amdjs/amdjs-api/wiki/AMD
  • 49. Refactor, Iteration 7: Modules - CommonJS • CommonJS’s module format was made popular for server-side JavaScript development (namely for Node.js/ NPM) • it’s synchronous • syntax is a bit easier as it frees you from the dene() wrapper that AMD enforces • requires a build in a JS runtime
  • 50. Refactor, Iteration 7: Modules - RequireJS • popular script loader written by James Burke that helps you load multiple script les and dene modules with or without dependencies • use RequireJS as rst pass at module loading since async nature means no build step during dev time (least disruption to the dev team which is important because there is a learning curve) • use almond (AMD API shim) so don’t have to add a special script tag to load RequireJS and change any HTML • this will move the code away from IIFEs to modules with dependency management
  • 51. my-app.js // requireJS simplified commonJS wrapper // do this so can use the commonJS style & // make switch to browserify easier define('app', function(require, exports, module) { 'use strict'; var $ = require('jquery'); var _ = require('underscore'); var Backbone = require('backbone'); var Modernizr = require('modernizr'); var HeaderController = require('./header-controller'); var FooterController = require('./footer-controller'); var app = new Backbone.Application(); module.exports = app; }); (function() { var $ = require('jquery'); var app = require('app'); // dom ready $(function() { app.start(); }); }());
  • 52. ; (function() { 'use strict'; var $ = require('jquery'); var PageOneController = require('./page-one-controller'); var app = require('app'); // dom ready $(function() { app.start({ ScreenController: PageOneController }); }); }()); page-one-main.js
  • 53. define('page-one-controller', function(require, exports, module) { 'use strict'; var Backbone = require('backbone'); var PageOneView = require('PageOneView'); var PageOneController = Backbone.Controller.extend({ initialize: function(options) { var pageOneView = new PageOneView(); } }); module.exports = PageOneController; }); page-one-controller.js
  • 54. define('page-one-view', function(require, exports, module) { 'use strict'; var Backbone = require('backbone'); var PageOneView = Backbone.View.extend({ }); module.exports = PageOneView; }); page-one-view.js
  • 55. Refactor, Iteration 7: Modules - Browserify • Browserify lets you require('modules') in the browser by bundling up all of your dependencies during a build step • it’s the end-state module loader because it allows for easy bundle splitting • gure out common/shared JS and create a common bundle then a bundle for the unique code on each page • by having a main.js for each screen this will act as an entry point so Browserify can nd all the modules required and create a screen-specic bundle
  • 56. Refactor, Iteration 7: Modules - Browserify • means build during dev but we were already doing that for our CSS with LESS • “It’s great the dev community has embraced compilation because it’s inevitable.” - Brendan Eich at Fluent 2015 • the code will become very clean
  • 57. 'use strict'; var Backbone = require('backbone'); var PageOneView = Backbone.View.extend({ el: '#pageOneMainContainer', initialize: function() {} }); module.exports = PageOneView; page-one-view.js
  • 58. Summary • the JavaScript is now modular and easier to maintain • Backbone.js helps devs keep consistent with coding patterns and organization (Object Literal notation, events) • events are scoped to the smallest part of the page to which they matter (Backbone.js) • namespacing/IIFEs and then later module loader/build removes the possibility of collisions with other frameworks/libs • unit tests mean you can feel more condent to change things • only sending JS to the browser that is necessary is good for performance (think mobile)
  • 60. "The secret to building large apps is never build large apps. Break your applications into small pieces. Then, assemble those testable, bite-sized pieces into your big application" - Justin Meyer, author JavaScriptMVC
  • 61. Team Shout Out • This was over the course of several years and I worked with two other fantastic front-end engineers: • Ryan Anklam ( @bittersweetryan ) • Zeek Chentnik ( http://ezekielchentnik.com )
  • 62. JavaScript References • “Patterns For Large-Scale JavaScript Application Architecture” by Addy Osmani 
 http://addyosmani.com/largescalejavascript/ • “Learning JavaScript Design Patterns” by Addy Osmani
 http://addyosmani.com/resources/essentialjsdesignpatterns/book/ • “Using Objects to Organize Your Code” by Rebecca Murphey
 http://rmurphey.com/blog/2009/10/15/using-objects-to-organize-your-code/ • “It’s time to start using JavaScript strict mode” by Nicholas Zakas
 http://www.nczonline.net/blog/2012/03/13/its-time-to-start-using-javascript-strict- mode/ • “Writing Modular JavaScript with AMD, CommonJS & ES Harmony” by Addy Osmani
 http://addyosmani.com/writing-modular-js/
  • 63. Backbone.js References • “Developing Backbone.js Applications” by Addy Osmani
 http://addyosmani.github.io/backbone-fundamentals/ • “Communicating Between Views in Client-Side Apps” by Rebecca Murphey
 http://bocoup.com/weblog/communicating-between- views-in-client-side-apps/ • Talks from past Backbone Conferences are free/online: http://backboneconf.com/
 http://backboneconf.com/2013/