Top Banner
MVC Performance Ember.js Standa Opichal @opichals
36

MVC Performance, Ember.js

May 17, 2015

Download

Technology

Standa Opichal

About how a core runtime and overall principles design influences the frontend framework performance.

Comparison examples from Ember.js and YUI3
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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