real world single page app - a knockout case study

Post on 22-Nov-2014

200 Views

Category:

Software

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

This presentation explores lessons learned from building a highly complex single page application that's used by 100's of automotive dealerships to finance and sell cars. We’ll walk through how to manage a pure client-side application with 1000’s of lines of custom JavaScript and review how Web API, Knockout, Durandal, RequireJS, KendoUI, and surprisingly little jQuery can join forces to make the browser sing. You’ll gain a clear understanding of when a single page app approach makes sense and learn how to pragmatically divide responsibilities between the client and server. This session will give you an appreciation for how far you can push ultra-responsive client-side rendering in the real-world.

TRANSCRIPT

REAL WORLD SPAA Knockout Case Study

Cory House @housecor

.com

Learn From My Mistakes

Knowledge Survey

Have you built a SPA?

Know Ember, Angular, Backbone?

Worked with Knockout, Durandal, Require, Fiddler, AJAX?

Here’s the Focus1. App walk-through

2. 10 Lessons Learned

3. Does this even make sense?

What monthly payment would you

like?

App Demo

New App: Two Goals

1. Cross Platform

2. Speed

10Lessons Learned

1Decisions are Hard.And we were wrong. A lot.

Sea of Decisions

but…

LightUnopinionatedLibrary

RichOpinionatedFramework

LightUnopinionatedLibrary

RichOpinionatedFramework

Pick a Language?!

Service Layer

WebAPI

And Pick a Promise Library…

Q RSVP

Bluebird jQuery

And a Testing Framework…

Utility Libraries

Data

Network TransportAJAX

Go 2-way:

WebSocket

AJAX Long-polling

Adobe® Flash® Socket

AJAX multipart streaming

Forever Iframe

JSONP Polling

Or punt:

NoSQL?

2Unobtrusive JSDead?

Unobtrusive JavaScript Movement: Dead?

1999 Inline

2007 Unobtrusive

Knockout

Angular

2013 Databinding

Databinding Advantages

Discoverability

Clarity

Less Code

Consider the Maintenance Programmer

Physically separating concerns that are logically intertwined without an explicit interface obfuscates rather than aids understanding.

3Bundle & MinifyMaybe not?

Heavy Load

93 JS

19 HTML

5 CSS

11 Images

----------------

132 HTTP requests?!

The Full SPA

93 JS files

53 viewmodels

9 libraries

39 Popup windows

56 HTML files

94 RESTful endpoints

Why Minify and Bundle?

1. Reduce HTTP requests to reduce load on server

2. Speed page load

3. Obfuscate code

Why Not Minify and Bundle?

1. Prod no longer matches dev

2. Risk of introducing obscure bugs

3. Debugging in prod is more complex

4. Complexity (and thus risk) must be justified

How’s Performance? It Depends.

Chrome IE8

Empty cache 6 13

Warm cache 3 3

Load first deal 1 2

Load second deal 1 2

Recalculate payment

1 2

To nearest second

4We’re blind to errors!That’s malpractice.

‘Twas Blind, but Now I See…

5Fast in Chrome?Meaningless.

Old IE, The Laggard

10x slower 5x slower

DOM Weight

Traditional

Duplicate elements rendered

Client-side

Single template

6Unix or Windows Mindset?No right answer.

Our Tech Stack

WebAPIORMLiteMSTest

KnockoutJS

Durandal

RequireJS

KendoUIKnockout.Mapping & Knockout-

KendoToastr

jQuery Q.js QUnit

Our Stack

Why Use Knockoutwith Durandal?

14% of our customers :_(

1. Convention

2. Composition

<div data-bind=“compose: ‘viewmodels/vehicle’></div><!-- ko compose: ‘viewmodels/vehicle’ --><!-- /ko -->

3. Routing

A Torrid Love Affair…

WebAPIORMLiteMSTest

KnockoutJS

Durandal

RequireJS

KendoUIKnockout.Mapping & Knockout-

KendoToastr

jQuery Q.js QUnit

Our Stack

WebAPIORMLiteMSTest

AngularJS

KendoUI

If We Used AngularJS instead…

7TypeScript or TestOr refactor at your own risk

My Awesome JS Refactoring Tool

And a Testing Framework…

What I’m testing:Service endpointsBusiness logicThat the data displays (implied)

8Architect Your JS like C#.DAL, BLL, Presentation…

Create a Client-Side “DAL”

JSON.stringify

Centralized service layer

Single wrapper around $.ajax

View

ViewModel

Service

AJAX service

Keep Your Viewmodels Thin

Create Business objects!

Instantiate them in your viewmodels

A 1,000+ line viewmodel is as smelly as a 1,000 class.

Avoid here.

Where Should I Put the Business Logic?

Prefer Here

9Config Object PatternDynamism belongs in JSON

JavaScript Configuration Object PatternJavaScript belongs in static .js files

Not strings in C#, Java, etc.

1 language per file

Inject dynamism via JSON from the server.

JavaScript Configuration Object Pattern

Config Object Pattern: A JustificationSeparation of concerns 

Caching 

Minimizes string parsing overhead

Code coloring 

Syntax checking

Reusable

Reduced payload 

Less abstraction

bitnative.com/2013/10/06/javascript-configuration-object-pattern/

1 Manage DependenciesKeep the global namespace clear.0

RequireJS

Utilizes AMD pattern

Dynamically load JS

Inject dependencies

Watch for circular dependencies

1Stay DRYDon’t repeat viewmodels on server & client1

var firstName = ko.observable(user.firstName);

var middleName = ko.observable(user.middleName);

var lastName = ko.observable(user.lastName);

Instead:

var user = ko.mapping.fromJS(user);

How Do I Stay DRY?

Use KO mapping plugin

Inject nullos via the Configuration Object Pattern

Ko.utils.

Does This Even Make Sense?

Why not?

Proprietary business logic

Low interactivity

Slower page load

Page is rarely called

Complex – Too many choices!

Debugging pain Runtime errors Cryptic One mistake and nothing loads

Why?

Responsive

Rich Interactivity

Separation of concerns

Efficient

Simple - Less abstraction Debugging No compile wait

Faster page load

SPA Experience Complete

Cory House

bitnative.com

@housecor

spkr8.com/t/35431

top related