MVC Performance, Ember.js

36
MVC Performance Ember.js Standa Opichal @opichals

description

About how a core runtime and overall principles design influences the frontend framework performance. Comparison examples from Ember.js and YUI3

Transcript of MVC Performance, Ember.js

Page 1: MVC Performance, Ember.js

MVC Performance Ember.js

Standa Opichal@opichals

Page 2: MVC Performance, Ember.js

MVC

Server Client

ViewControllerModel HTML

Page 3: MVC Performance, Ember.js

Single Page App MVC

Server Client

VCM HTMLVCM ?

Page 4: MVC Performance, Ember.js

SPA Load Performance

VCM HTML?

JS

VCM

ClientServer

Page 5: MVC Performance, Ember.js

Client MVC Performance

ViewControllerModel

Page 6: MVC Performance, Ember.js

Runtime PerformanceExpressiveness (Clarity + Brevity)Performance Conscious Concepts

Framework Performance

Page 7: MVC Performance, Ember.js

Instance ConstructionEventingKey-Value Observing

Runtime Performance

ViewControllerModel

Page 8: MVC Performance, Ember.js

JavaScript

var brendan = { name: ‘Brendan’};

Performance: very fastKVO: not really

Construction

Object

Page 9: MVC Performance, Ember.js

var eric = new Y.Base({ name: ‘Eric’})

var tom = Ember.Object.create({ name: ‘Tom’})

Construction: KVO

KVO

Page 10: MVC Performance, Ember.js

var tom = Ember.Object.create({ name: ‘Tom’

_nameDidChange: function() { }.observes(‘name’)

firstName: function() { }.property(‘name’)})

Construction: KVO

KVO

Page 11: MVC Performance, Ember.js

for (var i=0; i<10000; i++) {constructSingleKVO();

}

SynchronousBlocks browser event loop till finishedIs it fast enough?

Construction Performance

KVO

Page 12: MVC Performance, Ember.js

Expected Construction PerformanceTime

Loop

cou

nt

Expectation

KVO

Page 13: MVC Performance, Ember.js

Construction Performance WTFTime

Loop

cou

nt

RealitySynchronous for loop!? WTF?

GCView

ControllerModel

Page 14: MVC Performance, Ember.js

Lifecycle EventsInitializingDestroying

KVO Book KeepingObservers

Varies significantly with JSVM, Browser, OS

Construction Performance Summary

ViewControllerModel

Page 15: MVC Performance, Ember.js

Eventing

Barebone eventing in YUI vs Ember.js

Page 16: MVC Performance, Ember.js

Eventing: YUI

kvo.fire(‘export’, { report: item })

kvo.on(‘export’, function onExport(e) {e.report.focus(); // facadee.preventDefault(); // DOM-likee.stop();

});kvo.after(‘export’, function afterExport(e) {

e.report.loseFocus();});

Page 17: MVC Performance, Ember.js

Eventing: Ember.js

controller.send(‘export’, { report: item })

// route actionexport: function onExport(args) {

args.report.focus(); // facade}

Page 18: MVC Performance, Ember.js

Eventing Performance

Facading, DOM-like events, default actions-> Lots of throwaway instances

-> frequent GC events

Simple method calls win!

Page 19: MVC Performance, Ember.js

YUIkeyChange DOM-like Events

Ember.jsDeclarative Observer NotationEventing is not used

KVO

Page 20: MVC Performance, Ember.js

Ember.Object.create({name: ‘Tom’,content: Em.Object.create({ name: ‘Jerry’ }),

nameDidChange: function() {// this runs upon name change

}.observes(‘name’, ‘content.name’)});

Ember.js Observers

Page 21: MVC Performance, Ember.js

Ember.js wins

Observers do by design way lesswork to function

+ Declarative is also readable

KVO Performance

Page 22: MVC Performance, Ember.js

ExpressivenessTemplatesLive BindingsDependency Injection

Page 23: MVC Performance, Ember.js

Ember.js ExpressivenessApp.UserController = Ember.ObjectController.extend({

content: Em.Object.create({name: ‘Tom’

});firstNameBinding: ‘content.name’

});

user-template:User: {{firstName}}

Page 24: MVC Performance, Ember.js

Performance Conscious Design

On-DemandAsync

Page 25: MVC Performance, Ember.js

Ember.js wins

Observers do by design way lesswork to function

+ Declarative is also readable

Example: GoodData Dashboard

Page 26: MVC Performance, Ember.js

Server Data

var tab = { items: [ // items.length ~ 100

{ type: ‘filter’ },{ type: ‘report’ },{ type: ‘line’ },...

]}

Page 27: MVC Performance, Ember.js

Dashboard Model

Tab = Em.Object.extend({ // KVOitems: Array<TabItem>

})

TabItem = Em.Object.extend({type: ...

})

Page 28: MVC Performance, Ember.js

Materialization

Server Data -> Model Instances

var tab = Tab.create(tabData)var items = tab.get(‘items’);tabData.items.forEach(function(item) {

items.push(TabItem.create(item))})

Slow: Dashboard ~ 10 Tabs * 100 items

Page 29: MVC Performance, Ember.js

// Want no TabItem instances created at firstvar tab = Tab.create({tabData: tabData});

// On-demand TabItem creationtab.get(‘items’);

Lazy Materialization FTW

Page 30: MVC Performance, Ember.js

Tab = Em.Object.extend({tabData: {...}items: function() {

return this.get(‘tabData’).items.map(function(item) {return TabItem.create(item);

})}.property(‘tabData’),

})

Lazy Materialization

Page 31: MVC Performance, Ember.js

Tab = Em.Object.extend({tabData: {...}items: function() {

...}.property(‘tabData’),

_itemsDidChange: function() {var types = this.get(‘items’).filter(...);// does stuff every items/tabData change

}.observes(‘items’); // gets ‘items’ on Tab creation})

Does it work?

Page 32: MVC Performance, Ember.js

Tab = Em.Object.extend({tabData: {...}items: function() { … }.property(‘tabData’),init: function () {

set(‘tabData’, {});// not declarative, unclear why, ugly// -> sooner or later somebody// _will_ forget and refactor to declarativethis.addObserver(‘items’, this._itemsDidChange);

}});

Ugly on-demand addObserver

Page 33: MVC Performance, Ember.js

Tab = Em.Object.extend({items: function() { … }.property(‘tabData’),

_itemsDidChange: function() {var types = this.get(‘items’).filter(...);

}.observes(‘items’);});

Observers are initialized after the ‘items’ computed property materialization (a tab.get(‘items’) call)

Since Ember.js 1.0-rc8

Page 34: MVC Performance, Ember.js

Use of Object.observe()Would make observing asyncCurrent Chrome CanaryIn Ember 2.0 (?)

Performance Future

Page 35: MVC Performance, Ember.js

Thank You!

Page 36: MVC Performance, Ember.js