 about how we can write idiomatic ember apps that are both performant and productive. If you can see the slides clearly, you can look them up on bit.ly idiomatic-ember. That's idiomatic-ember. But first, we have a heavy heart. Let's address the elephant in the room. What's an idiomatic talk without idioms? They say time is money, so I'm just gonna cut to the chase. My name is Lauren, and I was born in the year of the rabbit. You can find me on the interwebs at Suga Pirate or Potato on GitHub. When I'm not working on client work or open source, I sometimes play Final Fantasy 14. It's an MMO that can be quite addictive, but thankfully I have 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. 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 as very many open source libraries, including Ember Adons. And in two days, it will be the end of my first year at Dockyard, and I have to say it's been one of the best jobs I've ever had. And the best part is, we're hiring senior Ember engineers. So please talk to me, Brian, Martin, or Estelle later if you're interested in finding out more. And if you come speak to me after my talk, I'll give you a very limited edition Suga Pirate sticker. 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. React has been daily gaining ground in mindshare and for good reasons. Some of its ideas, some of its ideas have even made their way into Ember and other frameworks. But despite how far we've come from our early days, modern web development is getting really hard. I mean, it used to be so simple, right? In the good old days, all you needed to do was write some HTML, maybe some CSS, slap some jQuery on a page and use a plugin or two or five. But these days, we spend so much time configuring things and we spend valuable time writing glue code and configuration instead of working on what matters for our applications. And you have to make a ton of choices for your front end stack, which can be quite paralyzing. And in some cases, it's also really easy to build a tangled web of dependencies, which can lead to all sorts of problems. It's tempting to fall victim to JavaScript hype and try to build your own makeshift framework that might end up slowing you down because you have to make sure everything plays nicely together. So why go through that pain? But that's why we use an opinionated framework like Ember, right? With Ember, we opt into convention over configuration and problems are shared across the community because chances are your app isn't a special snowflake. These strong standards have given the Ember community hands down the best tooling experience available. We have things like the Ember CLI, Ember Inspector, more than 2,000 add-ons, which is an incredible number. And all of this will not have been possible without you, the community. 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 really easy. There are a few people in there that don't seem to sleep. So if you have a question, there was almost always someone available to help you out. Now, because Ember is so 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 experience in building web applications. Now with Ember 2.0 being released last year in August, quite a few things have changed since then and those changes are the main motivation for my talk. For example, there has been a lot of discussion around data down actions up. This is a pattern for one way data flow that we've adapted and it's meant to make your apps easier to reason about and maintain. I'm gonna cover this in more detail later. We've also established conventions that singleton states should live in a service instead of a controller. Services are excellent for handling the long-lived state of things such as shopping carts, activity feeds, and notification messages. Now actions have been getting a little confusing in Ember 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. And we also know that controllers are going away sometime in the future. I'll talk a little bit more about what that really means and share some techniques you can use to ease the transition to a routable component. So in a nutshell, things have changed and dealing with changes can be hard. These changes can be difficult to deal with because things that used to be best practices may no longer be true and there is a general lack of updated information about the proper way of doing things. By going forward, we can expect to see Ember become more closely aligned with JavaScript and for things to become more explicit and less magical. ES 2017 features and beyond are gonna play a pivotal role in Ember's future. For example, you can already use decorators today using RWJ Boo's excellent add-on. This is currently a stage one proposal, but it's incredibly useful for drawing out your code. And the most obvious example is with a computer property. As you can see, this is a lot nicer than what we have to do today. Async await functions are also on the horizon and are one stage away from being included into the spec. These let us write asynchronous operations as if they were synchronous. Now, if you've ever been trolled by promises or async programming like I have all the time, for example, in RWJ Boo's RFC for making tests great again, describes how we might make use of async 08 to clean up our tests and as a result, our tests will be a lot easier to read and follow. Generator functions are also already a part of ES 2015 and they're really cool. They allow you to write cooperative code meaning you can pause, resume, restart them as well as end them early. And these are so powerful that you should check out MACD's add-on Ember concurrency, which I'm sure you've heard a lot of. It allows you to write tasks to do things you would have a really hard time replicating without a generator function. So as you can see when you use Ember, you're betting on JavaScript and we're gonna become more closely aligned with the latest JavaScript features meaning you'll be able to write more JavaScript and less Ember. I think it's fair to say that Ember is the solution to JavaScript hype fatigue and that is why I'm really excited to give this talk because with Ember, we no longer have to sacrifice performance for productivity. So in this talk, I wanna cast away any doubt you might have about what the Ember way really is and hopefully you'll be able to take away some ideas you can use straight away in your apps. Very broadly, I'll be speaking about patterns and anti-patterns in modern Ember apps. First, let's talk about an important concept. Data down actions up is one of the core principles that drive a modern Ember app. By architecting our applications in this manner, we can build apps that are easier to maintain and reason about. Data down actions up describes the flow of data through your app. For example, this is what your app might look like once a lot of components land. You fetch data from your API which gets normalized and pushed into your Ember data store. These records then get passed in as attributes to a lot of components and child components send actions up to modify that data. You might have noticed controllers are missing from their diagram and that's because they're gonna be deprecated and removed in the future. But why remove controllers if they already work? Well, the core team found that a component could easily take the place of a controller in view as components are superior implementations. Does this mean the death of NBC? No, but there has been a lot of confusion on this topic so I'm gonna address this in more detail later. What React taught us is that the biggest problems of the frameworks that predate it is the very thing that made them popular and that is two way bindings. Implested changes are hard to reason about and can very easily cause an infinite cascade of changes if you're not careful. When glimmer or angle bracket components land, data bindings will become one way by default and instead of mutating data, we will send actions up to update it and this becomes a really nice functional way of building applications that are still reactive and easier to reason about. By ignoring two way bindings and instead focusing on re-rendering multiple times efficiently through glimmer, we can have changes propagate immediately without introducing all the cascading semantics of a two way bind and this will be made possible with one way data flow and making renderers peer and idempotent. With data down acted up, a guiding principle is to ask who owns the data. Only the owner should be allowed to modify it and this is particularly important when the data is application state. We should strive to keep as single sources of truth. For example, here's a diagram of what a simple ember app might look like on a given route. Let's say that component A is only allowed to show one child component at a time and perhaps after doing some configuration in a child component, we need to programmatically show the next one. Now where would the best place be to do that? If we follow the data down acted up principle, we need to ask ourselves who owns the data and in this case, which configuration component to render is the concern of component A as it owns the shared state of all of its children. So in order to mutate the current step property, we need to send an action up to component A. What we must avoid doing is mutating the current step in the child component. It's a subtle difference, but it means an app that is easier to reason about and maintain and you won't need to spend hours figuring out who's changing what because you know there's only one place it's being changed. But the action is changing the property anyway, so why not just do it directly? Well, when you change the state that somebody else owns, you're stealing. And effectively it means that the owner no longer controls the data and you bypass the owner's interface. However, in the future, luckily for us, these problems will go away. Glimmer components will be one way by default. So even if you try mutating current step in the child component, it would not flow up to mutate the current set property of the parent component unless you explicitly opt into doing so with the mute helper. Another thing to note is that services can also own their own data and this is an important part of Data Down Actions Up and the Ember programming model. And this will be especially important to know when Rattable Components land, as Singleton State must be moved into a service because components are stateless. So if Data Down Actions Up and Rattable Components are coming, what do we do with controllers? So as I mentioned earlier, controllers aren't completely dead yet and you shouldn't try to avoid them unless you really want to. 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's gonna be implemented as a Rattable Component instead. You might still need to use a controller right now if you need query parameters or in certain cases a bubbling actions, but these will be moved to the route eventually when Rattable Components land. So as I said before, don't get too creative in trying to remove controllers. You should only do it when it makes sense. Ember 1.0 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 and view was doing could be better handled by a component in service. So the Rattable Component was introduced and the major difference you have to keep in mind is that a Rattable Component is not a Singleton like it's controller counterpart, but conceptually they should still do the same things which is decorate a model. A simple concept is to think of a Rattable Component as the unification of what we call a controller and view. And there are things you can do today to make this transition easier. Again, this is optional. You're not forced to do it, but it's a nice way to make your application a little bit future proof. The first key thing you can do is to move your route level template into a top level component. When Rattable Components land, it basically just moves that invocation into the route implicitly. 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. 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 Rattable Components land. However, actions that deal with UI or presentation logic should still remain on your Rattable Component or controller. There are some gotchas with moving controller actions to the route though, so I'm gonna share a way to do so a little later. But first, let's take a look at actions. Currently, I'm sure you'll agree with me, actions can be a little confusing in number. For example, you could define a classic action on the first line by giving it a string property of the action name or you could use a new style action on the second line. As a best practice, you should always prefer to use the new style or closure action. A new style action is essentially just a JavaScript function, which means you can do things like make use of return values, partially apply arguments and more. While classic or string actions are very implicit in nature and make things hard to debug. For example, it would be really easy to mistake submit for a string property and it would be difficult to trace where the action actually lives. And another thing is when you use classic actions, you have to remember to use send action in your components, which I kind of dislike and to me, it's kind of like sending your action into space because you send it up somewhere, you hope something's listening to it, who knows where it's going. And the worst part is it never comes back with a return value, it's kind of you flip. But on the other hand, new style actions are awesome. They're one of my favorite additions to Ember and they've been available since 113. Now don't let the word closure action or new style action scare you, it's really just a JavaScript function. As I said earlier, you have return values and this is especially useful when dealing with asynchronous operations like saving a record. You can return the same promise and then handle it from inside your component. For example, you might wanna handle success or failure states. So new style actions are awesome, but out of the box you can only use them if they're defined on your controller as they do not bubble like classic actions do. But if you wanna move your actions that deal with data to the route, this seems kind of lame. So RWJ Blue and I built a little add-on you can use today and it's called the Ember route action helper. 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. Now if you recall, controllers without routes could be created and it was a common practice to manage singleton state with them. A service is a long lift singleton we can use to manage long lift state. A great example for a service is a shopping cart or activity feed. For things that have singleton logic, you can extract that logic into a service and then inject it into the objects you need to. A shopping cart is an excellent example of a service because it can only be one singleton cart in the application and it needs to have long lift state throughout the life cycle of your app. And you can implement a cart if it's as little as setting a property on a service to be in an array or you could do more. But what we must be really 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 really bad sign and you should stop. Instead, you should adhere to data on actions up and not use a service for something that doesn't need long lift state. Now I want to talk about templating, something I'm sure is close to all of our hearts keeps us up at night. Another of my favorite new things in Inver is the new helper implementation. This was introduced in 113 and it's great for expressing presentational logic. For example, this equal helper can be found in the Ember truth helpers add-on which we pretty much use for all our apps. Ember itself also shipped through a bunch of really useful helpers like Concat, Hash, and the Get Helper. And the best thing about helpers is it basically lets you power up your templates. Again, because Ember is converging towards just being JavaScript, a helper is kind of just like a regular JavaScript function. And one of the reasons I like helper so much is that it forces you to keep your function small and free of side effects. You can basically create two kinds of helpers. This one is a simple one that will recompute every time the parameters change. But for more complicated needs, you can also make a class-based helper which is essentially an Ember object similar to the ones you've already been using. And this means you can do things like define computer properties on it, use a service, and so on. For example, this is a helper that looks up translations on the locale service. And specifically, you might want to listen for a change in locale, and then all the translations using this helper should automatically update, even though the locale itself was never passed into the helper explicitly. Some of you might have noticed that I used an observer in my previous example. Class-based helpers are currently the only place it's okay to use one because helpers are still a lightweight implementation, almost an MVP, and its lifecycle hooks are not implemented yet. But when those become available sometime soon, maybe, we can use them to recompute instead. Another reason 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 we're mixing data and UI logic together. So one thing you could do is split them up into two 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. Let's say we had a hypothetical helper called pipe. It would let you take the return value from one action and pass it along to the next one. And it would keep passing that value down to each function in the pipe. If you've used the programming language Elixer before, this pipe helper is essentially the same as the pipe operator, which lets you express the above, which really isn't very nice to read, as a series of data transforms, and this is a lot easier to read and understand compared to the first example. And since we use Elixer so much at Dockyard, it was a language feature we wanted to use in Ember. So the pipe helper was born to let you compose small, pure actions to allow more declarative templating. In this example, the item argument at the end gets passed into the first action, and then its return value gets passed into the next. As you can see, helpers are really powerful tools to extend templating in your application. And together with my colleague, Martin Skilstra, we've built an add-on called Ember Composable Helpers, which contains the pipe helper and other declarative helpers. Now 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 two separate actions called save and quit, and save and close, and save and blah. You can just compose them directly. That said, you should not get too ambitious with misting helpers inside of each other. And when your template looks like this, you're better off using a computed property instead. It can be very easy to get carried away with using helpers, and how much logic you wanna have in your templates depends on your comfort level and experience. So please use them with caution and exercise best judgment. But the point is, helpers are better suited for dealing with UI and presentational logic, which quite often is highly abstract and unrelated to the data in question, in contrast to computed properties, which are highly often coupled with data. But that brings us to our next question. When we do need to perform computation, what is the best way? Generally speaking, we have three ways of doing so. You could express it as a computer property, use a helper in the template, or use a component hook. Each approach has its pros and cons, so let's look at when we should prefer to use one over the other. Computer properties are one of the first things you learn about in Ember. They can be really powerful or really simple, and are a nice way of keeping some computation up to date. But these auto updates can be a double-edged sword because observing changes are implicit, so when a computer property recomputes, you don't always know why it did. The best analogy for computer property is an Excel spreadsheet. It would be really painful to sum A1 and B1 by placing event listeners on yourself and then getting their DOM values. A computer property lets you declaratively express that logic that changes automatically when the dependence change. And I would recommend using computer properties for expressing business logic. One of the best things about computer properties is that they can become reusable macros. And you can extract a computer property into a macro by creating a function that returns a computer property. You can then pass in any arbitrary keys or values into the macro, and then you can import it and use it like you would any other, like the ones that ship with Ember like computed and computed or et cetera. And this is a great way to dry up your code and test your business logic. Another awesome thing about computer properties is that they are cached, meaning expensive work is only done when it needs to be done. So basically computer properties are great for business logic and a potential for reuse in other Ember objects. They update when their dependence change, but you can subscribe to these explicitly by specifying the keys that the computer property observes. However, it can be sometimes difficult to trace why a computer property recomputes. Helpers can be simple functions or a class-based, and they don't have a DOM element, but they're simple to debug. You know what goes in and what comes out. And just like computer properties, we should strive to keep these pure and free of side effects. Helpers are best suited for generating utility functions and are especially useful for UI logic. For example, this little helper repeats the block inside of it three times. It's not really related to the business domain at all, but it helps us dry up our code and templates so you can use this nice markup instead of copy-pasting a bunch of HTML X number of times. Another thing to note about helpers is that Ember doesn't guarantee that multiple users of the helper will actually run at any given point. For example, this capitalized helper will only run once even though it's used twice. And this is a good thing as it means Ember can optimize rendering. But what that means for you is that helpers must be carefully written to not rely on side effects. You may also be surprised to note that helpers can even be used as an action if that helper returns a function. Again, this is really useful for expressing UI logic and we might use this toggle helper to toggle a dropdown or a popover or something else. And then you can use your action helper like this, which is a lot nicer than defining yet another toggle is expanded or toggle is displayed or toggle whatever action in your components. So helpers are great for UI and presentation logic and they're inherently composable with sub-expressions and nested helpers. And they're also really easy to understand and can be used as an action, which is really cool. And because they're still lightweight implementations, we sometimes have to use observers to trigger recomputation in the class-based helper. Component hooks are also a nice explicit way of handling computation. For example, when properties change from the outside, we can handle it really easily. However, component hooks can be quite tricky to use so you should prefer to use a computed property unless you know why you need to use a lifecycle hook. Life cycle hooks are best used when you need a side effect and they 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 the receive address to update the chart whenever new data flows into the component. This is a simple diagram showing the order of hooks that fire when components render or re-render. And when using these hooks, it's really important to think about whether the changes in your hook are idempotent. In other words, your hook should work no matter how many times they're called in the initial or updating case, as you cannot easily control the order and timing of these hooks. For example, this might look fairly innocent and you might wanna toggle some property after a component has rendered. But because this hook has side effects, it will cause a re-render, which fires the did render hook again, which re-renders and so on until your browser explodes. So in a nutshell, life cycle hooks are useful for replacing observers and for controlling side effects. However, they can also be potential foot guns as you can easily cause an infinite loop or cause sync issues if your logic is an idempotent. So please use them with caution. And finally, the age old question, should I use an observer? This topic has been covered quite in detail already, but basically you almost never want to use an observer. There are low-level primitives used by ember, so you don't have to. And as I mentioned earlier, the only place it's okay to use one right now is in a class-based helper because no life cycle hooks are available to use yet. So please remember, every time you use an observer, Stefan Penner dies a little inside. So don't do it. And please watch this Wicked Good Ember talk on observers, it's really great. I wanna close off the talk by briefly mentioning what we can learn from game renders and what the future might hold for the way we build web applications. Game renders are surprisingly similar to web applications. This diagram shows the rendering architecture for Doom 3, a popular first-person shooter. There is an idea of a front end and a back end as well as an intermediate representation that sits between. The front end captures the state of the world and determines what contributes to the view. This is then expressed as an intermediate representation which is then passed into the back end where it goes through a hardware abstraction layer like DirectX or OpenGL before reaching your graphics card and then your screen. Similarly, an Ember app captures the state of your application and determines what to render. Our templates go through HTML bars and Glimmer, then through DOM APIs, and this is then taken by a browser and rendered onto your screen. But if games and web applications are so similar, how come games that are so much more complex and graphically rich sometimes run faster than a web app? The answer is that games are heavily optimized to make use of your graphics card and they use a bunch of tricks like occlusion calling to optimize rendering performance. I'm really excited to see the trailblazing work, Chris Thobern or Ranspired is doing, you should follow him for updates. And in fact, Mozilla is actually working on an experimental web renderer for Servo that aims to draw web content like a modern game engine does. And early prototypes of this renderer are able to render existing websites at hundreds and hundreds of frames per second, which is very exciting. Now I won't go into too much detail about this, but you can check this video out for more information. But 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. To summarize, we looked at the state of JavaScript and we saw that Ember is gonna closely align itself to new features from ES 2017 and beyond. We then looked at what data down actions up means and how to implement it by keeping in mind who the owner of that data is and to avoid mutating data directly. Then we cleared the error and controllers, rightable components and services are superior implementations and we'll still play the part of a controller which is to decorate a model. We also looked at using the Ember route action helper for using route actions in your 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 you can use Ember composable helpers to make your templates more declarative. I wanna thank Dockyard for allowing me to give this talk and for being an awesome place to work at. We're organizing the Wicked GoodEmber conference this June, so please check out our website for more information. Once again, please get in touch if you have any questions and remember to speak with me if you're interested in working at or with Dockyard or if you have any questions about the talk. And I'll also give you a sugar pirate secretive. Thank you all so much for listening.