 It's because the title, haha, alright so my name is Steph, I'm from there, Wheat in Canada. I figured this for Americans you might understand this better than an actual map of the US, I mean of Canada. For a while I lived in New York, it was a lot of fun, I got to work with Luke, it was a great time. But since then I have moved to a relatively new job at Yahoo, I'm doing lots and lots of open source which is fantastic, it allows me to have fun and hobbies, so now when I told people I longboarded if I was in New York they understood what I meant, but when I was talking to someone on the other coast they're like, oh you surfed, I'm like no, but now I can unambiguously say that I can longboard, I'm not very good at it yet, but it is a lot of fun. When you fall down, you don't get as scratched up on the pavement as you do when you fall down on longboards, I also like giving talks like this one, I'm a husband with a very patient life, you guys may have seen my birds on Twitter, they like perch on laptops while you're pairing and they make you more productive, this is our other one except he eats headphones and power adapters so he can't pair, I suspect, well maybe I shouldn't say this, but our speakers, we got these little helicopters, flying helicopters, I'm excited to chase my birds around the apartment with it. For those of you who don't know, I'm also on the Ember core team, one of my primary responsibilities is Ember CLI, so I like to fix all the bugs, complain a lot on Twitter, hopefully not at people but about stuff, I know stuff is created by people but I complain about my own stuff often. I like to look at, working on Ember CLI and Ember and all of these things allows me to, if I can maybe fix a problem easier in one part of the stack, it just gets easier across the board, so being able to look at a big broad spectrum allows for some fun stuff. This talk won't be about broad spectrum stuff but very focused things I think we can do with our Ember apps to be a little bit more productive, but a recent addition to being on the Ember core team and all the stuff is I now attend TC39, so in addition to Yehuda there are now two Ember core team members who attend TC39. So I have to say I was really working at Yahoo allows me to attend TC39, and Yehuda had mentioned that maybe this is something I want to consider at some point, I was really apprehensive I didn't want to go, I just imagined like an unproductive three days of bike shedding, but I have to say after attending the first meeting I feel that the language isn't pretty good pens, there's a really good counterbalance, there's a lot of very strong academics, runtime implementers and consumers of JavaScript, I find that although there is some bike shedding, I think that it's an extremely, we're extremely lucky to have our hands in such a good strong committee, maybe in the past it wasn't so, but now it feels really good. Anyways, so going forward, assume that this is in front of all my code samples because well slides are small, yada yada yada, so at Yahoo we have a very large number of Ember apps and Ember developers, I think Mike and myself have tried to figure out what the exact number is and every week we find a few more people using Ember, so I don't even know how many people, but more than I know, but having so many developers looking at lots of code bases and then looking at common bugs that we have, there are two very related points that cause probably the most bugs, the first one is needs and controllers and the second one that amplifies the problems with needs is observers, so who here has an Ember app in production right now, that's really cool, a few years ago it would have been much less, who here has never used Ember before, graffiti, Mr. Graffiti there is too good to work with Ember, graffiti even has observers, so who here feels that they could live their life without observers and Ember, who has tried, so one of the fun parts of doing some code reviews at Yahoo is this discussion, it happens almost all the time, I see someone had added a few observers and I say what if there weren't no observers how would you solve this and it immediately turns into another comment being like you're crazy and I say come to my desk we'll talk about it and usually I think I've done this conversation enough times and been pretty successful with it that I'm gonna try to have it with all of you at the same time so we'll see how that goes, but when you're about to use an observer just think what if there are no observers how would this system work, I think we often use observers as like replacement for method calls or replacement for other stuff it's just a hammer and next time you're about to use an observer take a step back and just think about it a little bit before you actually use it, so one thing we've talked about haven't instituted yet is if you're about to use an observer imagine it cost you 20 bucks to use a single observer you're probably gonna think about it twice you're gonna really think about that case where you have a for loop over at observer to add a whole bunch of observers you're gonna really have to think about it and well out of all the scenarios I've seen so far there haven't been any where we have actually needed those observers so and the resulting code was much easier much more testable much less buggy and fun stuff anyways so I think ember we screwed up these two things look very much the same and they can sometimes appear like they're functionally equivalent so the top one is a computed property which returns the value of the concatenation of first name and last name and the second is an observer who observers return values don't really matter but they have the ability to set the value so these are fairly similar maybe on the outward and when we create these two objects so going forward friend will always be the computer property case and foe will always be the observer case you notice the first difference here that is when we create foe we don't get the full name but when we create friend we in fact do get the full name well why is this well there's this weird thing in ember where if you pass attributes to create they are considered as the initial state of the object meaning they're just how the object begins its life it's kind of strange to emit change events for that in ember there's this interesting thing called on in it which actually is after in it and if you add properties in on in it which is after in it change events do fire so there's this weird trick that you can do or you can actually do on in it on the observer which forces the observer to compute after initialization thereby basically in this very simple example making computer properties and observers appear pretty close to being the same thing so now once we've added that foe when I create them immediately full name is in fact full name success go home Alex has a great picture of Robert Jackson photoshopped on his face I couldn't find it I really wanted to find it but I couldn't anyways but so this actually isn't true let's take a closer look so I'm gonna throw in some logging and basically I'm just gonna log each of these computer properties and observers to kind of get a feel for what's actually going on so if I go and create friend I create them and then once I grab full full computes and it computes the full name unfortunately with the observer case full is computed eagerly the observable experience appears the same but this little detail actually burns us quite a bit so first lessons the difference between computer properties and observers are observers are eager so with basic scenarios it really doesn't make that much of a difference although it isn't maybe nice where it becomes fun is what if we added another dependent property so we have reversed which is just the reverse of the full name so in this case we may create a computer property where we created a dependent key that depends on full name and I just wrote the logging in there first time in addition to that I'll do the same thing for the observer case and then if we go back to our friend example when I get full it computes when I get reversed it lazily complete compute that computes unfortunately with observers they're both eager so observed experience looks the same but they're happening even if I don't need it if I never even want reversed or full extra work happens and something feels very fishy about this and then when I say this to people like well if only have a few models who cares right it's a little extra work it's not a big deal but this is the same people will like a week later come be like so embers really slow I have 4,000 models why doesn't this work so as part of the downside of observers is they have a huge work amplification potential so clearly observers are not computer properties observers are eager now there's a second twist on observers versus computer properties and that is consistency so imagine I a friend who currently has the first name of Stefan and the last name of Penner and then I go and I mutate first name and last name to be Eric Brinjolfson so Eric Brin is actually a Viking you can see proof by his legit last name and in the computer property case everything appears totally fine but in the observer case because full depends on first name and reverse depends on full as soon as I change first name reversed and full both compute and for a small period of time I'm gonna have Eric Penner and I don't think my wife or his girlfriend would be too thrilled about that so this is weird and if you guys have observers in your apps this is actually happening but then when you come for the second property set it corrects itself so you might not even know that you're doing copious amounts of strange work along the way only to get a very simple final answer again all these cases if you compound the properties and the pendant key chains it gets crazier but then finally when you sit lasted corrects itself yay eventual consistency blah blah blah now what you often see is inside of an observer people will do some kind of calculation and as a result of that calculation they might do something now it's probably dubious to be doing calculations inside of observers but this illustrates the problem fairly well you will basically have an indefined middle state where age and year are incorrect you can cause some funky funky states now there is a tiny workaround for very specific scenarios and you can use ember dot or object set properties and unfortunately that only works in the simple cases and they're really fun bugs you have objects in different parts of your app all setting it and there's no sane way to sort of coalesce all those things together unless you really understand the whole experience there's an opportunity where ember maybe could make observers asynchronous but if we just use computer properties just more or less just doesn't exist because they're lazy and on demand now if you guys can get anyone actually see that okay so I'm gonna read it it's kind of weird but remember the context is extremely important so your your hardness I finally adapted to it so I'm assuming this is some anime show and hopefully it's an appropriate anime show but one thing you lose with observers you don't know why you were invoked you have no idea what the system what happened in the system to cause your computer property to cause your observer to compute so a quick example again we have our foe friend here and we have a 2a bound input value and our client says whenever someone types first in the input I would like the model just auto-save I don't we have a cool UI we don't need a save button we just save all the time so developer throws in the observer is happy ships it well the first problem with this one is for every keystroke you're sending a jack's quest might not be ideal so the developer goes and he throws a debounce in the middle of that then he realizes in testing that the debounce is now causing him testing grief so he goes and cancels the test but not with observers a few months later the product managers like by the way we want everything to be real time when that employee and this employee both collaborate together we want data to flow back and forth and all of a sudden we're pushing data into the store and in the observer case this actually means our observers going to compute because full name may have changed so as as the user goes and type something they may get the message and now every two seconds because of the debounce we're actually going to be constantly saving and reloading the data so as a pro we have now implemented a really crappy form of synchronization but it really wasn't intended and in every one of these cases people when you talk about like you know I'll be careful in this case maybe I'll put my app in some mode when it's pushing or this well let me tell you a story what once upon a time only in Bangalore some of my coworkers may be laughing there was a moment js date range generation plus observer cycle happening so basically because of the time zone there was a glitch somewhere many observers in the system and when you were in that time zone at a specific time you would compute all the dates from like 1970 to now and it turns out moment js isn't necessarily the quickest library this particular function was de-opting so take precisely 15 minutes then it would release and the developer or the user could go on their merry way so interestingly the code that actually had these observers and all this fun stuff hadn't been touched in quite some time but it was just the shifting of data through the system that caused the cycle to happen in a strange way and because observers don't know why they have in fact been invoked they just receive any change as hey I got to do work these types of problems actually happen quite often hopefully not something that's time zone related but they still happen so the solution to this is we want to restore context when we actually make choices and we do stuff you may have heard this before it's the whole bindings down actions up thing well instead of doing the observer to see when first changes the solution would be when there's an event that gets emitted or an action that gets emitted and from that action the developer makes a choice so in the user when the input changes then I would actually explicitly like to call save so the cool thing about this is if first changes for any other reason then from user input you're not going to try to accidentally save something so now we have restored context and there's no real observer in this case that the developer has written and because we're pedantic we have the debounce we actually have to make sure to cancel the debounce when we destroy the object or we're gonna have pains in our tests and Steph won't debug them for you anymore next part of this is when I was thinking about the implications of observers is something very similar is the law of Demeter and this is a common oh law that basically states an object should only talk to its direct neighbors the further away it reaches from its direct neighbors the more brittle a system is going to get now there isn't really a law but it more or less is always true observers have a very similar problem and that is unexpected side effects are unexpected I love reading stuff that I wrote so very small little difference here between number one and number two and it makes actually massive difference in the first example old is implicitly two-way bound when first changes it will change the model the controller it will change many things when when new changes because it's opt-in it will only change it will only percolate the changes will only propagate as far as you've opted in to allow it to change so might be a little bit small all you need to know is the top is the model in the bottom is the template this is the old model input changes the component might change the controller might change the model might change the binding changes in any order doesn't really matter it's going to flow and in this scenario he'll probably work fine your app grows this starts to happen and then it grows and this starts to happen you change full name and all of your controllers that share that model that may have at one point cared about that model now start listening in on these changes making choices calling callbacks all this stuff and this is almost never the intention and so this is a real scary part about having non-optional two-way binding throughout a system and in this case observers that live at any one of these places they're eagerly computing so even if we had two-way data binding and no observers and only computer properties if no one is listening the computer properties which is do nothing but in the case of observers they're always doing crazy funny things and then it gets even better you connect all the controllers with needs you add routing and you have the funnest bugs that keep consultants extremely well-paid for a long time but there's a really easy solution to this and that is control the the scope of where these changes flow so in the new model in Ember basically bindings all these fun things are one way by default which means data just flows down if in fact you want to propagate data back up one level it is in fact your responsibility to opt in you can either use something like the mute helper or the previous example where you actually use an action where the user click save or an input event fired and you propagate it up now if in fact you want to propagate further it's again your choice does this mean it's slightly more verbose potentially but I think I don't think it actually will be more verbose but what it means is it means you know what the side effects are of what you're going to do so if we go back to the law of Demeter the big problem was sometimes your side effects are going to be brittle because your code changes but sometimes your side effects just reach far too far so it's kind of similar we probably need a better name for it but yeah the cool thing is now if we take the same model and apply it to the larger system our change actually only affected this tiny little part of the system and we don't have to worry about crazy repercussions who here who has big ember apps has had bugs where depending on which route they enter they have some bugs sometimes and not other times this is this problem and for the other people who didn't put up your hand you have this problem so by understanding the context why something changed by preventing huge side effect explosions which are costly and potentially resulting in inconsistent data and just bad stuff the best example is when you've routed into a deeply nested comment routed back out routed somewhere else and also now you have an error and some weird unrelated controller that's that inconsistency problem I showed before we have that if statement making a choice rather than it being a numerical comparison it's probably this object just doesn't exist yet because you've entered in a weird way but often it's just because observers have introduced synchrony throughout your entire application so here's a fun example just everything possibly you can imagine is wrong with this but it looks perfectly reasonable at first glance so first of all we have enemies controller which is connected to friends controller and anytime any full name changes on the friends controller save every friend so the first thing that happens here is if I go and change three full names we're actually gonna call that save three times synchronously and immediately the crazy thing is this controller may not even its template that matters may not even be in view anymore it may just be ambiently present doing its thing computing causing havoc making your app slow and hard to debug so the solution for this is actions up bindings down kill the observers use computer properties and everything becomes lovely picture kind of worked I like this guy so like I said before observers are the data binding hammer they exist why do they exist an ember in the first place I think when you're building a data binding system you're like well when that thing changed I want to do something it seems perfectly reasonable I think they're a great tool to maybe explore they might be a good primitive that exists that us as developers in apps shouldn't really interact with but ember definitely screwed up when they made computer properties and observers really feel like siblings in this world so there are a few examples were today in one X ember observers or maybe the tool you must use the only example that I can really think of that's a totally legit one is when you're pushing data out of ember so an example here is whenever data changes I would like to render a D3 component this makes perfect sense D3 isn't aware of embers observations this and it isn't aware of the chain tracking it isn't aware of these things so we have no choice but to when data changes push it into D3 and tell D3 to do its work you will notice though that this is a little bit more verbose than maybe what some people do when they write observers the first thing is when you're writing an observer observers are synchronous but computer properties are lazy and we want allow computer properties to continue to be lazy but if we have observers who synchronously pull data out of computer properties what happens is almost all of your computer properties now start feeling like observers because your observers are pulling at them immediately and people then wonder Steph's totally crazy observers and computer properties are totally the same thing but actually it's some component some select component deep in their application that's forcing computer properties to become synchronous so the solution is when in fact data changes we're going to schedule once on the render queue to draw but as soon as we schedule something once that's a little bit async inside embers run loop we actually have to still make sure that the current component is still in DOM it's totally possible that the same change that caused data to change made the component not be renderable anymore this is a little bit verbose but if you're using components or and observers today this is probably the approach you have to take actually this is the approach you will have to take now in theory we could shudder this up a little bit more and call it a day but in the new component render hooks that we have our lifecycle hooks that we have we can actually remove the observer the on did insert element all the guards all that fun stuff by just allowing ember to call a method that does the exact same thing so again no more can no more observers ember just has given us a better primitive that's called at the right point in time so we have sufficient context it's called only once it's called all the basically it's it's more or less what we implemented before but the framework is doing it for us so again if you have to use an observer today maybe you're still in the process of repacting your application try to push information out of ember you don't want to end up in a situation where in an observer you're setting properties if an observer you're setting properties you can absolutely just invert that make it a computed property again if you're using a observer you must schedule for laziness and ideally you want to schedule once for uniqueness and be very aware of the life cycles in play so if you're inside of a component be aware that your component may no longer be in Dom and then you shouldn't do any work does this sound like a pain in the ass absolutely and that's probably why you shouldn't use observers at all anyways so actions up bindings down and that's it are there any questions questions questions questions questions questions everyone totally feels good about this killing observers thing yeah no one feels bad about it so are there actual plans to actually do away with observers or just to discourage them not documenting them as much or when you document them to basically explain the use cases so I don't think there's ever a silver bullet for any problem I think observables observers or observables make an interesting primitive but they're just really hard to actually use in a consistent way so will ember eventually not have any observers it's entirely possible I don't know for sure but I think that in most cases where people want to use observers it's because there's some deficient API that is missing or they're just using them incorrectly what I would personally like to see is for observers to be much more ugly to use so they're slightly more discouraged when you use them but there might be some part of the API or you need to experiment for now to add on to that what I've the only time I usually see myself or using observers is actually during debugging I will throw in an observer just literally to see what's going on with with you know a computed property or or some state in something when when something changes that's honestly the only reason why I use observers would you is there any pattern you'd recommend instead instead of creating like an ad hoc no I think that's a great pattern to use observers when debugging hopefully not when you're debugging other observers though that might be a little bit of a little bit of a nightmare I think observers I think there's a future for object observes or object observations in the in the language itself but I think its purpose is really as a low-level primitive to get access to something that there is just no other way to reasonably do maybe in fact that would be sufficient maybe you'll have enough fewer caveats than our current observation system but it does feel like a primitive that can be useful especially when experimenting and potentially debugging so another time I found the need for observers is like making a computed property with a dynamic dependent key like using ember dot ad observer and then specifying a model and then a property that's a variable that pass in oh yeah so for those that didn't hear the question was he has an example where an observer is used to add to basically emulate the fact there's no concept of a dynamic dependent key inside of a computer property most scenarios that I've seen that are actually solved by the actions up data down thing most the time when data is actually changing it's as a result of something that happened it's very uncommon actually for you just to be poking your way through an object graph and be like anytime this random thing in the far corner changes do something it's just a very strange and unnatural thing actually there might be use cases that I'm not seeing I haven't encountered any so far so if you have a good one let me know I'd love to play with it and hopefully give you a better solution with the browser implemented observer would that be more performant than the ember observer that being option yeah so if the JavaScript runtimes implement object observes or object at observations the first thing I believe they will be is they will be asynchronous so one of the things with embers observers is they do fire immediately whereas what will actually in theory happen depending on where the spec lands is when you change a pojo's first name you changed immediately twice you will only know the last time that it changed so what that means is you don't have that eager consumption problem in addition to that it should be significantly faster than then the system that we've implemented although interestingly this weird side effect with how observers work if you have observers in the controller or computer property today and you're moving around your app and sometimes it feels sluggish often it's actually the last controller that you left or last component that you left and you're going to a new one it's the last one that's cleaning up because people will have like prepare controller or clean up controller calls in their routes it's actually the cleanup that's causing all of these side effects to happen that's causing performance problems so observers are really not terribly slow but it's actually these unexpected side effects that typically cause massive performance problems any other questions so this isn't so much of a question but the single biggest case where we see observer abuse at Yahoo is where some component does not fire an action and someone's trying to use data binding to respond to a change in some value so when you're building components make sure you are providing a first-class way to bind actions as well because that's that once you introduce into the system like something that you're just listening for value changes to this observer and it starts to just bleed through the whole app yeah like I said before if you have that one observer pulling eagerly your entire system all sudden becomes eager and slow and brittle and all that fun stuff so sometimes it's just as easy as fixing one component so as you guys rewrite more awesome components at emberadons.com make sure that they don't use these poor practices I'm not I've never done iOS development but I know like a lot of concepts in ember come from that world or you know the cocoa world in general is this a pattern that has is this a performance optimization that has been done in cocoa where people are relying more on whatever their equivalent of CPs are moving away from observers so if I say anything I have no idea I'll just be bullshitting you maybe someone else Luke do you have any thoughts on that no let's just assume maybe well thank you very much if anyone has any more questions you can find me afterwards or bug me on Twitter