emberconf 2016 – idiomatic ember (speaker notes)

70
IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY EMBERCONF 2016 IDIOMATIC EMBER Finding the Sweet Spot of Performance & Productivity · DOCKYARD· hi everyone! today i want to share some ideas with you about how we can write idiomatic ember apps that are both performant and productive IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY EMBERCONF 2016 bit.ly/idiomatic-ember if you can't see the slides clearly, you can look them up on bitly idiomatic dash ember (repeat it)

Upload: lauren-elizabeth-tan

Post on 12-Apr-2017

372 views

Category:

Engineering


2 download

TRANSCRIPT

Page 1: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

IDIOMATIC EMBERFinding the Sweet Spot of Performance & Productivity

·D O C K Y A R D · • hi everyone! • today i want to share some ideas with you about how

we can write idiomatic ember apps that are both

performant and productive

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

bit.ly/idiomatic-ember

• if you can't see the slides clearly, you can look them up

on • bitly idiomatic dash ember (repeat it)

Page 2: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• but first with a heavy heart, let's address the elephant

in the room – • what's an idiomatic talk without idioms?

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• they say time is money • so i'm gonna just cut to the chase

Page 3: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

🐰 LAUREN TAN ! SUGARPIRATE_ " POTETO

• my name is lauren, and i was born in the year of the

rabbit • you can find me on the interwebs as sugarpirate or

poteto on github

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• when i'm not working on client work or open source, i

sometimes play final fantasy 14 • it's a game that can be quite addictive, but thankfully i

have

Page 4: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

🐶 ZELDA

• a little puppy Zelda who keeps me grounded in reality • unfortunately she couldn't be here today to give this

talk, so you'll have to listen to me instead

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

I WORK AT DOCKYARD

• a year ago i was still living in australia • but i moved to Boston last year to work at DockYard • we work on a ton of Ember and Elixir apps as well very

many open source libraries including ember addons • in 2 days it will be the end of my 1st year at dockyard,

and i have to say that it's been one of the best jobs i've

ever had

Page 5: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• the best part is, we're hiring senior ember engineers • so please talk to me, brian, marten or estelle later if

you're interested in finding out more

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• and if you come speak to me after my talk, i'll give you

a very limited edition sugarpirate sticker!

Page 6: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

THE STATE OF JAVASCRIPT IN 2016

• now before we start talking about ember, let's look at

what it's like to build a modern javascript app in the

year 2016

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• react has been steadily gaining ground and

mindshare • and for good reasons • some of its ideas have even made their way into ember

and other frameworks

Page 7: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• but despite how far we've come from our early days, modern web dev is getting really hard

• i mean, it used to be so simple, right?

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• in the Good Old Days™, all you had to do was write some

html, maybe some css, slap some jQuery on a page • and even use a plugin or 5

Page 8: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• but these days we spend so much time configuring

things • and we spend valuable time writing glue code instead

of working on what matters

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• you have to make a ton of choices for your front end

stack • which can be quite paralyzing

Page 9: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

leftpad

• & its easy to build a tangled web of dependencies • which can lead to all sorts of problems… • <dramatic pause> 🙃

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

“I hand-rolled my own front-end stack using the most organic, gluten-free

and artisanal micro-libraries.”

🤓

• it's tempting to fall victim to javascript hype • and try to build your own makeshift framework • that might end up slowing you down bc you have to make

sure everything plays nicely together • why go through that pain?

Page 10: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• but that's why we use an opinionated framework like ember, right?

• with ember, we opt into convention over configuration • problems are shared across the community • bc chances are, your app isn't a special snowflake

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Performance Productivity

• these strong standards have given the ember community

hands down the best tooling experience available • we have things like ember-cli, the ember inspector, more

than 2,000 addons, which is an incredible number • and all of this would not have been possible without the

community

Page 11: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

❤❤

• and i think it's fair to say that ember has one of the most welcoming and friendly communities out there

• our slack channel is always active, and getting help is easy • there are a few people in there that don't seem to sleep • so if you have a question, there will almost always be

someone available to help you out

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

THE EMBER WAY?

• because ember is opinionated, it also means there is

an "ember" way of doing things • instead of rebuilding the wheel and inventing your own

abstractions • we leverage the community's exp in building web apps • with ember 2.0 being released last year in august, quite

a few things have changed since then • changes are main motivation for talk

Page 12: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Data

Component

Owner

Action

• for example, there has been lots of discussion around

data down, actions up • this is a pattern for one way data flow that we adapted • and is meant to make your apps easier to reason about

& maintain • i'll cover this more in detail later

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• we've also established conventions that singleton

state should live in services instead of controllers • services are excellent for handling the long lived state

of things such as shopping carts, activity feeds and

notification messages

Page 13: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

this.attrs.fooAction(val);

this.get('fooAction')(val);

VS

• actions have been getting a little confusing lately • with the future introduction of glimmer components • these action calls will be subtly different, although

they may appear to be the same right now

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• we also know that controllers are going away in the

future • i'll talk a little more about what that means and share

some techniques you can use to ease the transition to

routable components

Page 14: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• in a nutshell, things have changed • and dealing with change can be hard • these changes can be diff to deal with bc • things that used to be best practices may no longer be

true • and lack of updated info about new way of doing

things

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

MORE JAVASCRIPT

• going forward, we can expect to see Ember become

more closely aligned with JavaScript, and for things to

become more explicit and less magical

• ES2017 features and beyond are going to play a pivotal

role in Ember's future

Page 15: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

DECORATORSStage 1

https://github.com/wycats/javascript-decorators

• for example, you can already use decorators today

using rwjblue's excellent addon

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016https://github.com/rwjblue/ember-computed-decorators

@computed('first', 'last')name(first, last) { return `${first} ${last}`;}

• this is currently a stage 1 proposal, but is incredibly

useful for DRYing up your code

• the most obvious example is with CPs, as you can see

this is much nicer than what we have to do today

Page 16: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

ASYNC/AWAITStage 3

https://github.com/tc39/ecmascript-asyncawait

• async/await functions are also on the horizon, and are

1 stage away from becoming included into the spec

• these let us write asynchronous operations as if they

were synchronous

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

await fillIn('.display-title', 'Hello!');await click('.update-display-title');

assert.equal(find('.display-title').text(), 'Hello!');

https://github.com/emberjs/rfcs/pull/119

• if you ever been trolled by Promises and async

programming, you'll love this new feature

• for example, in rwjblue's RFC for making tests great

again, he describes how we might make use of async/

await to clean up tests

• as a result, code & tests are much easier to read and

follow

Page 17: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

GENERATORSES2015

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*

• generator functions are already a part of es2015

• and are really cool

• they allow you to write co-operative code – you can

pause, resume and restart them as well as end them

early

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

countingTask: task(function* () { this.set('count', 0); while (this.get('count') < 5) { this.incrementProperty('count'); yield timeout(300); } this.set('count', 'DONE!');}).restartable()

https://github.com/machty/ember-concurrency

• these are really powerful, and you should definitely

checkout Machty's addon called ember-concurrency

• it allows you to write Tasks to do things you would have

a hard time replicating without generator functions

Page 18: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• as you can see, when you use Ember, you're betting on

JavaScript

• we're going to become even more closely aligned with

the latest JS features, meaning that you'll be able to

write more JavaScript and less Ember

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

– Yehuda Katz

“All good ideas will eventually end up in Ember.”

• i think it's fair to say that ember is the solution to

javascript hype fatigue

• and that is why i'm excited to give this talk, bc with

ember, we don't have to sacrifice performance for

productivity

Page 19: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

THE EMBER WAY 🙏

• so in this talk, i want to cast away any doubt you might

have about what the ember way really is

• and hopefully you'll take away some useful ideas you

can use straight away in your apps

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

I. Data Down, Actions Up?

II. Controllers are Dead

III.Declarative & Composable Templates

• very broadly, i'll be speaking about patterns and anti-

patterns in modern ember apps

• first, i want to talk about an important concept

Page 20: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

I. Data Down, Actions Up?

II. Controllers are Dead

III.Declarative & Composable Templates

• data down actions up is one of the core principles

driving modern ember apps

• by architecting our applications in this manner, we can

build apps that are easier to maintain and reason about

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• data down, actions up describes flow of data thru

app • eg this is what app might look like once routable

components land • fetch data from API, which gets normalized and

pushed into ED store • records then get passed in as attrs to routable

component

Page 21: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• you might have noticed controllers were missing

from that diagram • and that's because they're going to be deprecated and

removed in the future

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Is MVC Dead? ☠

• but why remove controllers if they already work? • well, core team found that a component could easily

take the place of a controller + view, as components

are superior implementations

Page 22: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Is MVC Dead? ☠NOPE

• does this mean the death of MVC? • no, but there has been a lot of confusion on this topic,

so i'll address it in more detail later

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

2 WAY BINDINGS 💣

• what React taught us is that the biggest problem of

the frameworks that predate it is the very thing that

made them popular • and that is two way bindings • implicit changes are hard to reason about, and • you can very easily cause an infinite cascade of

changes if you're not careful

Page 23: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

💎

• when glimmer or angle bracket components land,

data bindings will become one way by default • and instead of mutating data, we will have to send

actions to update it • this becomes a nice, functional way of building

applications that are still reactive • and easier to reason about

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• by ignoring 2 way bindings and instead re-rendering

multiple times efficiently, we can have changes

propagate immediately without introducing all the

cascading semantics of a 2 way bind • and this is made possible with one way data flow and

making renders pure and idempotent

Page 24: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Who owns the data?

• with DDAU, a guiding principle is to ask who owns

the data • only the owner should be allowed to modify it • this is particularly important when that data is

application state, which we should strive to keep as

single sources of truth

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Component A

Component A.1 Component A.2 Component A.3

Route

Owns the shared state of A1 - A3

• for example, here's a diagram of what a simple ember

app might look like on a given route • lets say Component A only allowed to show 1 child

component at a time • perhaps after doing some config in a child component,

we need to programmatically show the next one • where would the best place be to do that?

Page 25: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Component A

Component A.1 Component A.2 Component A.3

Route

Owns the shared state of A1 - A3

{{component configComponent user=user changeStep=(action "changeStep")}}

• if we follow the DDAU principle, we need to ask

ourselves – "Who owns the data?" • In this case, which config component to render is the

concern of Component A, it owns the shared state of

all its children • so, in order to mutate the current step property, we

should send an action up to Component A

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

{{component configComponent user=user currentStep=currentStep}}

// don't do this in the child component!

export default Component.extend({ actions: { next() { set(this, 'currentStep', 'configure-foo'); } }});

This is bad ☹

• what we must avoid doing is mutating the

"currentStep" in the child component • it's a subtle difference, but it means an app that is

easier to reason about and maintain • you won't need to spend hours figuring out who is

changing what • because you know there is only one place it is being

changed

Page 26: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

…or someone else's state!

• but the action is changing the property anyway, why

not just do it directly? • when you change the state that someone else owns,

you're stealing • effectively it means that the owner no longer controls

the data and you have bypassed the owner's interface • however, in the future these problems will likely go

away

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

<configure-username user={{user}} currentStep={{currentStep}}> ...</configure-username>

• Glimmer Components will be 1 way by default • so even if you tried mutating `currentStep` in the child

component, it would not flow up to mutate the

currentStep prop of the parent component • unless you explicitly opt-in to doing so with the `mut`

helper

Page 27: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Service.extend({ init() { this._super(...arguments); this.data = []; }});

• another thing to note is that services can also own

their own data, • and this is an important part of the Ember

programming model • this will be especially useful to know when routable

components land, • as singleton state must be moved into a service bc

components are stateless

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

I. Data Down, Actions Up?

II. Controllers are Dead

III.Declarative & Composable Templates

• with ddau and routable components coming, what do

we do with controllers?

Page 28: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• so, as i mentioned earlier

• controllers aren't completely dead yet…

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

ROUTABLE CONTROLLER

• one important thing to note about controllers is that

the concept itself isn't going away

• however, the implementation is changing

• essentially, the concept of a controller decorating a

model still exists, but it is implemented as a routable

component instead

Page 29: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Controller.extend({ queryParams: ['category'], category: null});

• you might still need to use a controller right now if you

want to use query params and in certain cases of

bubbling actions

• but these will be moved to the route eventually when

routable components land

• that said, don't get too creative in trying to avoid

controllers, only remove when it makes sense

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

ROUTABLE CONTROLLER

• Ember 1.x was a straightforward implementation of

MVC, we had a controller and a view

• but we've deprecated views in favor of components

• and it turns out that what the controller + view was

doing could be better handled by a component and

service

Page 30: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

ROUTABLE COMPONENT

• so the routable component was introduced

• the major difference you have to keep in mind is that a

routable component is not a singleton like its controller

counterpart

• but conceptually, they should do the same things,

which is decorate a model

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Component = Controller + View

• a simpler concept is to think of the routable

component as the unification of what we call a

controller and a view

Page 31: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

<h1>Alpaca Route Template</h1>

<div class="my-amazing-template"> {{#each alpacas as |alpaca|}} <span> I'm a cute little {{alpaca}}! </span> {{/each}}</div>

{{foo-alpaca alpacas=alpacas}}

move to

• there are things you can do today to make this

transition easier

• the first key thing you can do is to move your route-level

template into a top-level component

• when routable components land, it basically just moves

that invocation into the route implicitly

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

// shopping-cart top-level componentexport default Component.extend({ shoppingCart: inject.service(),

actions: { remove(product) { // ... } }});

{{#each shoppingCart.products as |product|}} <h2>{{product.title}}</h2> <p>{{product.description}}</p> <button {{action "remove" product}}>Remove</button>{{/each}}

• the reason it's a good idea to use a top level

component now is that it forces you to separate your

stateful, singleton logic out and into a service

• a transition to a service for the stateful bits and a

component for the stateless bits is most likely to be

future proof

• and will make the transition an easier one

Page 32: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Controller

Action

Action

Action

Route

Action

Action

Action

move to

• another thing you can do is to move actions that deal

with data to the route

• these actions are likely better located in the route as

that is where they'll eventually live when routable

components land

• however, actions that deal with UI or presentational

logic should remain on the routable component

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

ACTIONS 🎬

• there are some gotchas with moving controller actions

to your route, so i'll share a way to do so a little later

• but first, let's take a look at actions

Page 33: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

{{foo-bar submit="submit"}}

{{foo-bar click=(action "submit")}}

• currently, actions can be a little confusing

• for example, you could define a classic action on a

component by giving it a string property of the action

name

• or you could use a new style action

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

New-style Actions 👍aka Closure Actions

• as a best practice, you should always prefer to use a

new-style or closure action

Page 34: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

{{foo-bar click=(action "submit")}}

• a new-style action is essentially just a regular

javascript function

• which means you can do things like make use of return

values, partially apply arguments and more

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Classic Actions 👎aka String Actions

• while classic or string actions are very implicit in

nature

Page 35: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

{{foo-bar submit="submit"}}

• and make things hard to debug

• for example, it would be easy to mistake submit for a

string property

• and it would be difficult to trace where the action

actually lives

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

this.sendAction('someMysteriousAction', args);

• another thing is when you use classic actions you have

to use `sendAction` in your components

• which is kinda like sending your action to space

Page 36: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Your classic action

• because you send it up somewhere and hope

something is listening to it

• who knows where it's going

• and the worst part is it never comes back with a return

value

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

get(this, 'submit')(...args);

• on the other hand, new-style actions are awesome

• they're one of my favorite additions to ember and

they've been available since 1.13

Page 37: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• don't let the word new-style or closure action scare

you

• it's really just a regular javascript function

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

actions: { saveAndDoStuff(item) { get(this, 'save')(item) .then((savedItem) => // do stuff); }}

• as i said earlier, you have return values

• these are especially useful when dealing with async

operations like saving a record

• you can return the save promise and then handle it

from inside the component

• e.g. handle success and failure state

Page 38: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

ember install ember-route-action-helper

https://github.com/DockYard/ember-route-action-helper

• so new-style actions are awesome, but out of the box

you can only use them if they're defined on the

controller as they do not bubble like classic actions

• but if you want to move your actions that deal with data

to the route this seems rather lame

• so rwjblue and i built a little addon you can use today

• it's called the ember-route-action-helper

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

{{foo-bar value=value updateFoo=(route-action "updateFoo")}}

• by using `route-action` in place of `action`

• this lets you have new-style actions that work with

routes, and when the time comes, you can search and

replace route-action back to action

Page 39: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

SERVICES

• if you recall, controllers without routes can be created,

and it was a common practice to manage singleton

state with them

• a service is a long lived singleton we can use to manage

long lived state

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• a great example for a service is a shopping cart or

activity feed

• for things that have singleton state, you can extract that

logic into a service and then inject it into the objects

you need to

Page 40: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Service.extend({ init() { this._super(...arguments); this.cart = []; },

addToCart(item) { // ... },

removeFromCart(item) { // ... }});

• a shopping cart is an excellent example of a service,

because there can only be one singleton cart in the

application, and it needs to have long lived state

across the app

• you can implement a cart with as little as setting a

property on a service to be an array

• or you could do more

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• what we must be careful about is not to abuse services

• if your main reason for creating a service is to use it as a

global bucket to avoid passing things around, that's a

bad sign

• instead, adhere to data down actions up and don't use

services for something that doesn't need long lived

singleton state

Page 41: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

I. Data Down, Actions Up?

II. Controllers are Dead

III.Declarative & Composable Templates

• now i want to talk about templating, something i'm

sure is close to all of our hearts

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

{{if (eq fullName "Jim Bob") "You're the chosen one"}}

https://github.com/jmurphyau/ember-truth-helpers

• another of my fav new things in Ember is the new

Helper impl

• introduced in Ember 1.13 and great for expressing

presentation logic

• for example, this `eq` helper can be found in ember-

truth-helpers addon, which we pretty much use for all

our apps

Page 42: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

{{concat "configure-" configName}}

http://emberjs.com/api/classes/Ember.Templates.helpers.html

• Ember itself also ships with a bunch of useful Helpers

like `concat`, `hash` and the`get` helper

• the best thing about Helpers is that it basically lets you

power up your templates

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

import Ember from 'ember';

export function add([a, b]) { return a + b;}

export default Ember.Helper.helper(add);

• again, because Ember is converging towards just being

JavaScript

• a helper is really just a regular JavaScript function

• one of the reasons i like helpers is that it forces you to

keep your functions small and free of side effects

• you can basically create 2 kinds of helpers, this one is a

simple one that will recompute every time the params

change

Page 43: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Helper.extend({ // ...});

• for more complex needs, you can also make a class

based helper, which is essentially an ember object

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Helper.extend({ localesService: inject.service('locales'), currentLocale: readOnly('localesService.currentLocale'), compute([key]) { let currentLocale = get(this, 'currentLocale'); return get(this, 'localesService').lookup(currentLocale, key); },

localeDidChange: observer('currentLocale', function() { this.recompute(); })});

• this means you can do things like define CPs, use

services and so on

• for example this is a helper that looks up translations

on a locales service

• specifically you might want to listen for a change in

locale

• and then all the translations should auto-update, even

though the locale itself is not passed into the helper

Page 44: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• some of you might have noticed i used an observer in

my previous example

• class based helpers are currently the only place it is ok

to use one

• bc it is still a lightweight implementation (almost mvp),

and its lifecycle hooks are not implemented yet

• when those become available, we can use them to

recompute instead

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Component.extend({ isDropdownDisplayed: false, actions: { saveUserAndHideDropdown(user) { get(this, 'save')(user) .then((user) => { // do stuff set(this, 'isDropdownDisplayed', false); }); } }});

• another reason i like helpers is because it means a lot

of UI logic can be moved back to where it belongs

• for example, how many times have you written

something like this?

• this feels a little dirty because it mixes data and UI logic

together

Page 45: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Component.extend({ isDropdownDisplayed: false, actions: { hideDropdown() { set(this, 'isDropdownDisplayed', false); }, saveUser(user) { return get(this, 'save')(user); } }});

• so one thing you could do is to split them up into 2

actions right?

• but now you have a problem, because you can't invoke

them both

• what i'm about to show you demonstrates how

powerful helpers can be

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

<button {{action (pipe saveUser hideDropdown) user}}> Save and Close</button>

• let's say we had a hypothetical helper called `pipe`

• it would let you take the return value from 1 action, and

pass it along to the next one

• and it would keep passing that value down to each

function in the pipe

Page 46: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

A(B(C(D('E'), 'F'), 'G'), 'H');

• if you've used the programming language elixir before,

this pipe helper is essentially the same as the pipe

operator

• the pipe operator lets you express the above, which

isn't very nice to read, as

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

filing = DB.find_customers |> Orders.for_customers |> sales_tax(2016) |> prepare_filing

E|> D|> C("F")|> B("G")|> A("H")

http://elixir-lang.org/

• a series of data transforms

• this is a lot easier to read compared to the 1st example

• since we use Elixir a lot at DockYard, it was a language

feature we wanted to use in ember

Page 47: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

<button {{action (pipe addToCart purchase redirectToThankYouPage) item}}> 1-Click Buy</button>

• so the pipe helper was born to let you compose small,

pure actions to allow more declarative templating

• in this e.g. the item argument at the end gets passed

into 1st action, then its return value piped into the rest

• as you can see, helpers can be really powerful tools to

extend templating in your app

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

ember install ember-composable-helpers

https://github.com/DockYard/ember-composable-helpers

• together with my colleague Marten Schilstra, we've

built an addon called ember-composable-helpers

• which contains the pipe helper and other declarative

helpers

Page 48: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

<button {{action (pipe save closeDropdown) item}}>Save and Close</button><button {{action (pipe save quitApp) item}}>Save and Quit</button>

• the best part about helpers is composability

• helpers can do things that might be more complex to

express in your component

• using the pipe helper example again, you don't need to

define 2 actions called `saveAndClose` and

`saveAndQuit`, you can just compose them directly

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

{{#if (eq (not (incr (count user))) (decr (count user))))}}

💩

• that said, you shouldn't try to get too ambitious with

nesting helpers inside of each other

• and when your template looks like this, you're better off

creating a CP instead

Page 49: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• it can be easy to get carried away with using helpers

• how much logic you want to have in your templates

depends on your comfort level

• so use them with caution and exercise best judgement

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• the point is, helpers are better suited for dealing with

UI / presentational logic

• which quite often is highly abstract and unrelated to

the exact data in question

• in contrast to CPs which are coupled to data

Page 50: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• which brings us to our next question

• when we do need to perform computation, what is the

best way?

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

COMPUTED VS HELPER VS COMPONENT HOOKS

• generally speaking, we have 3 ways of doing so

• you could express it as a CP, use a helper in the

template, or use a component hook to set a value

• each approach has its pros and cons, lets look at when

we should prefer to use one over the other

Page 51: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

COMPUTEDS

• CPs are one of the first things you learn in Ember

• they can range from simple to powerful, and are a nice

way of keeping some computation up to date

• but these auto updates can be double edged sword

• bc observing changes are implicit, so when a CP

recomputes, don't always know why it did

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• the best analogy for a CP is an excel spreadsheet

• it would be painful to sum a1 and b1 by placing event

listeners on the cells and then getting their DOM values

• a CP lets you declaratively express logic that changes

automatically when the dependents change

Page 52: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Component.extend({ @computed('payment', 'rate', 'periods') annuity(payment, rate, periods) { let factor = ((1 - Math.pow(1 + rate, -periods)) / rate); return payment * factor; }});

• i would recommend using CPs for expressing business

logic

• one of the best things about CPs is that they can

become reusable macros

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export function customMacro(dependentKey, ...keys) { return computed(dependentKey, ...keys, { get() { // computed property logic } });}

• you can extract a CP into a macro by creating a

function that returns a CP

• you can then pass in any arbitrary key or value into the

macro,

Page 53: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Component.extend({ myValue: customMacro('myKey', 'foo', 'bar'), someValue: customMacro('someKey', 'baz', 'qux'), otherValue: customMacro('otherKey', 'meow', 'woof')});

• and then you can import and use it like you would any

other macro

• this is a great way to DRY up your code and test your

business logic

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• another awesome thing about CPs is that they are

cached

• meaning expensive work is only done when it needs to

be done

Page 54: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

💪👔👍 Business logic

👍👍👍👍 Reusable

⚛⚛⚛⚛ React to changes

🤔 Changes can be implicit

Totally arbitrary emojis• so basically CPs are great for business logic and have

potential for reuse in other ember objects

• they update when dependents change, but you can

'subscribe' to these explicitly by specifying keys

• however it can be sometimes difficult to trace why a CP

recomputes

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

HELPERS

• helpers can be simple functions or class based

• they don't have a DOM element and are simple to

debug – you know where the data is coming from, and

what comes out of it

• just like CPs, we should strive to keep these pure and

free of side effects

Page 55: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

{{#each (repeat 3) as |nil index|}} <div data-thing={{concat "foo-" index}}> {{!some HTML block}} </div>{{/each}}

https://github.com/DockYard/ember-composable-helpers#repeat

• helpers are best suited for generic utility functions,

and are especially useful for UI logic

• for example, this little helper repeats the block inside of

it, 3 times

• it's non-business logic related but helps us DRY up our

templates, so you can use this nice markup instead of

copy pasting a block of HTML 3 times

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

{{capitalize "hello"}} {{capitalize "hello"}}

• another thing to note about helpers is that ember

doesn't guarantee that multiple uses of the helper will

actually run at any given point

• for example, this capitalize helper will only run once,

even though it's used 2x

• this is a good thing as it means ember can optimize

rendering

• but that means helpers must be carefully written to not

Page 56: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export function toggle([obj, prop]) { return function() { set(obj, prop, !get(obj, prop)); };}

https://github.com/DockYard/ember-composable-helpers#toggle

• you may or may not be surprised to note that helpers

can be used as an action if it returns a function

• again, this is really useful for expressing UI logic, we

might use this toggle helper to toggle a dropdown or a

popover

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

<button {{action (toggle this "isExpanded")}}> {{if isExpanded "I am expanded" "I am not"}}</button>

• you can then use your action helper like this,

• which is much nicer than defining yet another

`toggleIsExpanded` action in your components

Page 57: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

🎨🖌 Express UI logic

✍❤📖 Composable

😶💭 Simple mental model

🏃 🏃 Can be used as action

🕵🔬🔍 No hooks available (yet)

Totally arbitrary emojis• so helpers are great for UI and presentational logic

• & inherently composable with sub-expr or nested

helpers

• they're easy to understand and can also be used as

actions

• & bc they're still lightweight implementations, we

sometimes have to use observers to recompute

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

COMPONENT HOOKS

• component hooks are also a nice explicit way of

handling computation

• for example, when props change from the outside, we

can handle it easily

• however, they can be quite tricky to use, so you should

prefer a CP unless you know why you need to use a

lifecycle hook

Page 58: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Component.extend({ didReceiveAttrs() { this.updateChart(get(this, 'data')); },

updateChart(data) { // update the chart's data }});

• lifecycle hooks are best used when you need side

effects, and should be preferred over an observer

• for example, you might have a component that wraps a

chart library which has some kind of render method

• you can use a hook like `didReceiveAttrs` to update the

chart whenever new data flows into the component

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Initial Render

init

didReceiveAttrs

willRender

didInsertElement

didRender

External attr changed

didUpdateAttrs

didReceiveAttrs

willUpdate

willRender

didUpdate

didRender

Internal value changed

willUpdate

willRender

didUpdate

didRender

• this is a simple diagram showing the order of hooks

that fire when components render or re-render

• when using these hooks, its important to think about

whether the changes are 'idempotent'

• in other words, these hooks should work no matter how

many times they are called

• as you cannot easily control the order and timing of the

hook

Page 59: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

export default Component.extend({ didRender() { // this is an infinite loop that will crash your browser let isFoo = get(this, 'isFoo'); set(this, 'isFoo', !isFoo); }});

• for example, this might look like fairly innocent

• you might want to toggle some property after a

component has rendered

• but because it has side effects, it will cause a re-render,

which fires the `didRender` hook again, which re-

renders, and so on until your browser explodes

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

🐘💨🙊 Dealing with side effects

😭➿😱 Can cause infinite loops

🔨🔨 "Just re-render it"

🚀🚀🚀 Not invoked in FastBoot environment

Totally arbitrary ratings• in a nutshell, lifecycle hooks are useful for replacing

observers and for controlling side effects

• however, they can also be potential footguns, as you

can easily cause an infinite loop or sync issues if your

logic is not idempotent

• so use them with caution

Page 60: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

SHOULD I USE AN OBSERVER?

• and finally the age old question, should i use an

observer???

• this topic has been covered quite in detail already,

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• but basically, you almost never want to use an

observer

• they're low level primitives used by ember so you don't

have to

• as i mentioned earlier, the only place it is ok to use one

is in a class based helper bc no lifecycle hooks are

implemented yet

Page 61: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

https://youtu.be/vvZEddrClAQ

• you should remember that every time you use an

observer, Stefan Penner dies a little inside

• so don't do it

• and watch his Wicked Good Ember talk on observers

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

THE FUTURE

• i want to close off the talk by briefly mentioning what

we can learn from game renderers

• and what the future might hold for how we build web

apps

Page 62: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• game renderers are surprisingly similar to web

applications

• this diagram shows the rendering architecture for

Doom 3

• there is an idea of a "front end" and a "back end" as well

as an Intermediate Representation (IR) that sits

between

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Game world state Front End IR Back End

DirectX / OpenGL

OS

Screen

• the front end captures the state of the world and

determines what contributes to the view

• this is then expressed as an IR, which is then passed

into the backend where it goes through a hardware

abstraction layer like DirectX or OpenGL before

reaching your GPU and then your screen

Page 63: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Application state Front End HTMLBars Glimmer

DOM APIs

Browser

Screen

• an ember app is similar

• we capture the state of the app and determine what to

render

• our templates go through HTMLBars and Glimmer, and

then to DOM APIs

• this is then taken by your browser and rendered onto

your screen

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• so if games and web apps are so similar

• how can games that are so much more complex and

graphically rich sometimes run faster than a web app?

Page 64: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Hidden blocks rendered, CPU time wasted

Line of SightCamera

Without occlusion culling

• the answer is that games are heavily optimized to

make use of your GPU

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Hidden blocks not rendered, CPU time saved

Line of SightCamera

With occlusion culling

• & use a bunch of tricks like occlusion culling to

optimize rendering performance

• i'm really excited to see the trailblazing work Chris

Thoburn (@runspired) is doing in this area, you should

follow him for updates

Page 65: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• in fact, Mozilla is actually working on an experimental

web renderer for Servo, that aims to draw web content

like a modern game engine

• early prototypes are able to render at hundreds of FPS

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

https://air.mozilla.org/bay-area-rust-meetup-february-2016/#@1m53s

• i won't go into further detail, but you can check out the

video for more info

• i think web apps have a lot to learn from game

rendering, and i'm excited to see us moving in that

direction to optimize performance

Page 66: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

TL;DR

• to summarize

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• we looked at the state of javascript and we saw that

ember is going to closely align itself to new features

from ES2017 and beyond

Page 67: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

I. Data Down, Actions Up?

II. Controllers are Dead

III.Declarative & Composable Templates

• we then looked at what DDAU means and how to

implement it by keeping in mind who the owner of the

data is

• and to avoid mutating data directly

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

I. Data Down, Actions Up?

II. Controllers are Dead

III.Declarative & Composable Templates

• then, we cleared the air on controllers

• routable components and services are superior impl

• & will still play the part of a controller, which is to

decorate a model

• we also looked at using ember-route-action-helper for

using route actions in templates

Page 68: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

I. Data Down, Actions Up?

II. Controllers are Dead

III.Declarative & Composable Templates

• and finally, we looked at ways to power up your

handlebars templates

• helpers are a great way of performing UI logic in a

composable and easily testable way

• you can write your own or use ember-composable-

helpers to make your templates more declarative

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• i want to thank dockyard for allowing me to give this

talk and being an awesome place to work at

Page 69: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

• we're organizing the WickedGoodEmber conference

this june, so please check out our website for more

info

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

🐰 LAUREN TAN ! SUGARPIRATE_ " POTETO

• once again, please get in touch if you have any

questions

Page 70: EmberConf 2016 – Idiomatic Ember (Speaker Notes)

IDIOMATIC EMBER – FINDING THE SWEET SPOT OF PERFORMANCE & PRODUCTIVITY

EMBERCONF 2016

Thanks!

🐰 LAUREN TAN ! SUGARPIRATE_ " POTETO

• remember to speak to me if you're interested in

working AT or WITH DockYard

• and i'll give you a sticker too

• thank you all so much for listening!