 quite starting yet, but before we start, I would like to give you a fair warning. What is gonna happen in the next half an hour is you'll see a lot of very dense and technical content. There will be TypeScript code involved. It would probably not help you with your job and you might actually want to reconsider going to Micsonics component talk and say it's gonna be a great talk and it's gonna be very practical. It's gonna help you with your job and you should only stay here if you're up for really, really dense technical content. You have been warned. No one's taking a bit, okay. All right. Couple people. Okay, so let's get started. Hello, I'm Godfrey. You can find me on the internet as Cheney and Code. If you were around last year, you might remember me as one of your favorite speakers with glowing reviews from Twitter like I have no idea what this talk is about and the Chanking Code deliberately misspelled temperature. You may also remember me as a Canadian or perhaps for my very important technical contributions such as the Canadian style sheet spec. As you can see, it fixes some of the glaring typos in the CSS spec and made a lot of things more polite in general. So. Ah. This is actually an Ember CLI add on you can get today but unfortunately it doesn't have a lot of points on Ember App Server because it didn't have enough downloads but nothing can fix with a few hundred people in the same room. I'm sure you can fix that for me. Anyway, unfortunately I talked on a new job last year with a company called Tilder. Since they're located in Portland, I have no choice but to move Canada to Portland so I'm very pleased to be your first speaker at the Conference of Welcome to Portland Canada. If you don't believe me, you can look at my bio that says my job title is in House Canadian at Tilder and it's listed on the conference website so you know it's true. Anyway, with my credibility blown away from last year's talk, I figured the best way to recover from that is to do a really technical talk with Yehuda and so you probably hear from Glimmer2. So Glimmer2 is a huge project. Yehuda and I have been working on this for over half a year and they're just way too much content to fit into a 30 minute talk so I just want to warn you that there will be a lot of hand waving going on in this talk and yeah, but I figured that would fit in pretty well with the conference theme anyway. Before we begin, I just want to thank Tilder and LinkedIn for sponsoring our time to work on Glimmer2 without the help we probably couldn't take on such an ambitious project. You probably don't know this, but LinkedIn is a really cool company. As you can see, they own the most punishable two letter word in the entire English language so as you can imagine, there are a lot of puns everywhere in the office but I don't think they realize the full potential of the assets, so I decide to give them some suggestions if they hopefully they don't mind. I think their signs that the parking lot could use some work and perhaps they should rename their design team and I fixed their website for them and I also fixed their ad campaign. If you know anyone from LinkedIn's marketing department, please consider hiring us for a next campaign. Anyway, with all that out of the way, let's get started. Glimmer2, so throughout the history of Ember, we have always bet pretty hard on declarative templates. In fact, the original goal of the Ember project was to add template support to SproutCorp and one of the things we love about templates is that it's just HTML and CSS. You already know how to write them and your designers already know how to write them and HTML and CSS is great and but that's easier said than done because there are actually a lot of edge cases in the HTML spec but thankfully it's carefully spec so people who work on browser know how it works so the best way to handle all the edge cases in HTML and CSS is basically to implement the HTML spec and we did that with HTML parts. We have a spec compliant HTML parser. It supports SVG and all the weird things in there and I think that result pays up and the other thing we like about templates is that they're very declarative and it turns out declarative is just a fancy way of seeing their pure function of states but more importantly they're actually FRP programs, whatever that means. Basically means they're programmed that you can run over and over again to get the latest result put them on screen. So I guess I will leave the rest to Yehuda and have a rest. The rest about a minute. Unfortunately we only had a three minute budget for jokes and God free took the whole thing so I'm just gonna die right in. So the core primitive of Glimmer is the reference data structure. Fundamentally a reference is just a stable object that represents the result of a pure side effect for computation where the result of the computation might change over time. So here is the interface, this is if you know TypeScript, this is like the simplest interface you could possibly write and if you know, if you've read anything about FRP this is pretty similar to a discrete FRP signal. The key difference between references and similar constructs in other libraries including in Glimmer One is that references are completely pull based with no notion of subscriptions or notifications. What we found through experience having done this for a few years now is that a pull based system is a better fit for the kind of problems we're trying to solve especially when maximum efficiency is at stake. So to give you an idea for the flavor of references let's make a very simple reference that captures the foo variable over its lifetime. This is a very simple example but it illustrates the power of the reference abstraction. Even though JavaScript variables always contain values that can be passed around and held onto by other functions variable bindings themselves in JavaScript are not a first class value. The idea behind references is that using the reference system is trivial to pass a variable by reference hence the name for the reference data type. To give you, sorry. Now interestingly because the reference is such a simple concept to begin with it's very easy to compose two references. So we're gonna look here at the thing which is the ad reference so we have the foo plus bar reference and hand wave hand wave you don't have to know exactly how this works but it's pretty small you can see the composition works pretty nicely. It's therefore also really easy to create functional combinators for them and in fact it's very easy to write the usual functional combinators that you would have expected from any streaming kind of primitive as long as it makes sense for discrete values. I can't go into this too much more but reference also has a lot of other foo properties. For example, they are also a natural fit for lazy evaluation which makes it easy to implement things like short circuit Boolean logic correctly. Okay, sorry. So at a high level this slide what this slide is saying is a template that you've seen before. Each of the curlies here is represented by a reference on the initial render we're gonna pull a value out and an update what we're gonna do is we're gonna pull a value out and replace. So with that, that's a very, if that felt simple you're probably gonna be okay if that felt complicated. Good luck. I caught. So while it is cool that the core reference interface is so simple and so flexible they could also be hiding or encapsulating arbitrarily expensive computation under the hood. Therefore it's usually a good idea to avoid recomputing reference value more often than necessary. In particular, because references are modeling pure computations that means they're basically just taking some inputs and making some outputs based on the inputs and if the inputs then change then there's no reason to reevaluate the value of a reference. For example, helpers and handlebars are required to be pure functions that operate solely on its input arguments. So if the arguments didn't change then the result of the helper invocation also wouldn't change. And here we have two hypothetical helpers, concat which joins the arguments together into a single string and uppercase which takes a single string as input and capitalize all the letters in the string. So let's see how we can model that as references. Let's start with the uppercase helper. The uppercase helper basically describing a simple map operation that takes a single input and apply one-to-one transformation on it. The implementation is pretty simple. Basically takes a single reference as input and to compute the value it takes the value from the input reference which returns a string and called to uppercase on it. The concat helper is a pretty similar story except that it's describing a reduced operation that takes multiple inputs and reduce them into a single value. The implementation is pretty similar though. It takes an array of references as input and to compute the value it evaluates all the references into an array of strings and then it called join on the array to arrive at a single string. As you can see the inputs of both of these helper reference are very clearly enumerated. Uppercase reference is a map operation that takes a single input reference as input so it should only be recomputed if and only if the input reference also needs to be recomputed or if the input reference has changed. On the other hand the concat reference is a reduced operation that takes an array of references as input. Therefore it needs to be recomputed if and only if any of the inputs has changed. This presents a recursive problem. If we have a way to determine the freshness of the input references then we also know how to model the freshness of these helper references. In other words we need a system that allows us to describe the freshness of a computation in terms of its inputs. This is exactly what the validation system in Glimmer is designed to do. The core primitive here is called an entity tag. An entity tag is a stable object that provides certain guarantees about the freshness of a computation or a computation result. Specifically an entity tag has a value method on it that returns an opaque validation ticket. When you want to catch a computation you should also acquire a validation ticket from the associated tag. This ticket can later be passed back into the validate method on the same entity tag to determine the freshness of the catch value which returns a Boolean value indicating whether the catch is still good or not. More specifically or more accurately it determines whether the catch result might have changed since the validation ticket was printed. I can't spend too much time on this but so let's set aside the fundamental question of how to derive freshness in the first place and focus on the composition aspect of the validator system. So let's say we have an extension to the reference interface that requires each reference to have a corresponding tag. This tag will tell you whether you need to recompute the value of a reference again. Now again we're just assuming this tag works by magic for now but with this primitive we can go back to the helper references. More hand wave. Here we have updated the uppercase helper reference to implement the tag reference interface. So to satisfy the interface we need to have a tag on the reference. Not a problem though. Here we're trying to express that if the input reference didn't change then the uppercase reference also didn't change. So we can just proxy the tag from the input reference directly. The concat reference is slightly more involved because we need to combine all the input tags into a single tag but the concept is not that complicated. The idea is pretty simple. Instead of having to give our single value as the concat reference validation ticket you hand out an array of validation tickets and recheck all of them against each of the upstream tickets during revalidation. So while the entity tag system is pretty cool and very flexible if we are willing to forego some of those flexibility we can implement that much more efficiently. In Glimmer we use a specialized version of the entity tag system called revision tagging. This system pairs a global revision counter with a per object revision counter which I can't get into too much details here but the biggest benefit of the approach is that when it allows us to compress an arbitrary number of validation tickets into a single integer making it significantly more efficient to use both store and compute the revalidation result. More in wave. There are a lot of details that we couldn't cover here but I've started to write a mini book on the Glimmer repo with a lot more details that I couldn't cover here so you should check it out after the talk. So all right let's take a deep breath everyone. We have just went through a very quick tour of the Glimmer primitives but how do we actually build a rendering engine out of that? So brace yourself we are leaving the station again. I would like to give you a very quick high level overview of how the Glimmer runtime works and one of the biggest realization when we're building Glimmer 2 is that the template is actually describing an FRP program so we should just do whatever the programming language implementers usually do to make the program as fast as possible. So we built a JIT compiler in a bytecode VM for our templates. So what does that actually mean? So what happens when you have a template like this and you want to render that in Glimmer 2? The first step actually happens at build time. When you run Ember built in a terminal it first compiles that into something we call the wire format. Here's a formative version of the wire format but it's basically just a simple representation of the pre-compiled template. This allows us to front load some of the costs of parsing the template at build time so users don't have to pay any of the costs. Notably we switch from emitting JavaScript functions in JavaScript code in Glimmer 1 to emitting a JSON object in this step in Glimmer 2 which is how we reduce the template size by five times. And furthermore because it's now data not code the browser doesn't have to eagerly eval the code and we can defer some of the parsing costs until the template is actually needed. Before your template is rendered for the first time to the user we run the wire format through the runtime compiler to produce a list of instructions for our virtual machine. And for simple operations like a panning a stack string to DOM it's pretty much a one to one compilation but for more complicated syntax like the if conditional the compilation is a little bit more involved. If you have worked with assembly or byte code VMs before the compilation is probably roughly in line with what you expect otherwise it might be a little bit intimidating but you can safely hand wave that away. The point of this runtime compilation phase is that we can take advantage of the information we have at runtime and code them into a program that we can reuse when we render the same template over again in the future like for example you might switch away from Run World and then you press the back button and you have to re-render that template from scratch again. Or the most obvious case of this is you have a loop and there's a single component inside the loop and you're repeating it over and over again you only have to do this work one time for the entire loop. Right, so a concrete example is when we see a simple curly or in other words a curly bracket with a single string inside it at build time we don't actually know whether that is a variable lookup or what is a helper invocation or a component invocation because they all have the same syntactical form. However at runtime we can do the triage once and for once for each template and avoid repeatedly asking that question over and over again as we re-render the template in the loop or in a different route. So finally when we actually get to executing this program two different artifacts will be produced in the process. First it would render this template into the DOM as you would expect because that's kind of the whole point of this thing. And but more importantly it also produced an updating program that you could run again to re-render the template. Now even though the original template might look pretty complicated there are only exactly two dynamic things here that needs to be dirty checked every time. If you still remember the things we went through in the first half of the talk each of these curlies here are represented by a single reference inside the updating off code. Furthermore we also take advantage of the revision tagging system to avoid rechecking anything in most cases. This is how we got to the 60 frame per second re-rendering performance you saw in the keynote yesterday. Finally when we're developing this obviously it's very important that we understand what our program is doing so we build this visualizer thing that you can type in some live templates and play with look at the compilation output and play with the result. And with that I'm gonna pass it to Yahuda to talk about some optimizations and future work. So the point of this section over here is to say that if you thought what we already did was pretty cool it's actually sort of the front line the first line of what we can do and I'm gonna present a bunch of optimizations that we were planning on doing in the future that are relatively small deltas of what we've already done. In fact the first one is an optimization that we already did. One of the earliest optimizations that we targeted and what we already implemented is what we call the constant optimization. So if you take a look at, this is an example of the optimization at work when we landed the PR. So as Godfrey says we always take a look at the visualizer when we're working on an optimization try to figure out what's going on. And one way to think about this is that there's a lot of, when you have a component you might have some properties in the component that are dynamic. You might say for example let's say using the font awesome library. You might have FA icon equals and then something dynamic. Or you might say FA icon equals and then the string bug. And if you say the string bug obviously there's a lot less things that can actually change in practice. So in this case what we were able to do is, and this was actually, it was more like what we were doing before was unnecessarily stupid. But interestingly if you don't have this architecture in the first place it's hard to figure out exactly what's going on. So the short version of this is to say if there's a constant value that's somewhere floating around when we construct a reference for the constant value we remember that it's a constant value. And then whenever we have any dynamic updating step that we would want to emit based on the input value if we see that the input value is constant we just don't bother emitting the updating opcode. There's no reason to even emit it. And in Glimmer references can say that they're constant and we will avoid doing work. This, and so here's another part of that same change. This same optimization could be applied to an immutable JS object in a read-only field as well as the unbound helper. So expressing that something is unbound would do the same thing. And we get a lot of leverage out of this. Once we land this optimization it actually had pretty significant macro effects because in real applications actually do have a decent amount of constant values that come from the template in natural ways. Second of all the VM architecture also makes it pretty easy to do adaptive optimizations based on runtime information. So let's say that the FA icon component doesn't happen to have a component class. So if you look at what happens when you, in the visualizer what happens when you start running a component is that we have to, there's a bunch of stuff on the bottom right over there that represents the component and we have to run it and it does things like run lifecycle hooks, construct the component in the first place, et cetera, et cetera. And the point of this optimization is that if we see that there's no component we can pretty much eliminate the vast majority of that work. But we can only do that once we notice that there's no component class at runtime. We can also do this again once at compile time and we get the benefit of the optimization every time the template is called which is very important in loops, but also if there's the same component used many times we only have to do this work one time. But further, let's say that we have a component that doesn't have a component class and the template is very simple. So let's say the simplest way to implement the FA icon component is you just, it's a template that has a I tag in it and says class equals FA icon, FA icon and then like FA curly curly for the input, right? And again, there's really no reason that you should not be able to just take the result and inline it at compile time. Of course, usually people's architectures can't figure that out, but the idea is that we wanna do something about this. So if you invoke it like again with a dynamic value it's hard to do something very good but if you invoke it with a static content you would like to effectively replace the invocation with literally just I class equals FA icon, FA bug and eliminate the component entirely. And the glimmer architecture, so this optimization that I just talked about which is basically noticing that the thing that you're trying to do is relatively simple and just doing the work, the evaluation at compile time. This is a thing that I've had in mind literally from the beginning of the glimmer two work and it's something that we built the entire architecture to make this optimization a layup. So the idea here is that if you look at the visualizer, the bottom right, the FA icon op codes, there's like 10 op codes there. What we can do is we can simply, we can basically eliminate all those op codes because almost we know for a fact that all the things that it's doing are free. Another optimization that we've had in mind is chunk rendering and the idea behind chunk rendering is you would like to be able to stop what you're doing so people have observed that basically you start rendering and some time goes by and the user's trying to scroll and things are janked and they're like oh if only I could just pause and let the browser go back and then come back to the rendering after a millisecond and then keep doing that in batches wouldn't that be awesome? And this is something that is an architectural question it's not always so easy to break in the middle especially if most of the work is happening in user code. In our case because of the fact that again if you look at this thing what's happening is a big list of op codes and we have an interpreter loop that's just running the op codes one at a time. It's actually quite easy for us to say some amount of time has gone by, okay given that that amount of time has gone by we'll just yield to the browser and then when we come back we'll just continue from exactly where we picked off. We haven't written this optimization yet but the actual architecture is a bunch of calls to .next so it's very easy to just not call .next and then start calling it again later. So again because the glimmer rendering is an interpreter loop it's pretty trivial for us to pause and resume the process at any time which will give us responsiveness which is also pretty important for rehydration. The idea behind rehydration as you might know is that we render the entire content on the server and then update it once it gets to the client. The thing about rehydration is that that is also pretty straightforward with glimmer and that's because all operations in glimmer go through an element stack which basically works with the DOM you can see that this is basically an implementation of the HTML parser algorithm. It's a spec compliant implementation of the non-error subset of the HTML tree builder algorithm. So for example if there's an operation that calls createElement on the element stack during rehydration all we have to do is say instead of actually creating elements we maintain a cursor position and instead if createElement is being called and the cursor is sitting in front of an element with that same tag we simply return that element instead of creating a new one. So we replace just this interface here these 10 or so methods with something that knows how to process an existing DOM and that's it. The rest of the system works exactly the same. I'm not announcing glimmer native because I'm not working on that but it is also the case that the process of executing a glimmer template itself is highly abstract. Here are the interfaces that deal with components so there's nothing really stopping somebody from implementing the component interfaces in a different way that was designed specifically for native. Again remember that all that's happening with your template is it's emitting a bunch of op codes and the interfaces that you would need to implement glimmer native are already extracted so you can do something different. Finally, if that wasn't enough the interfaces that you need to build the entire interface of the entire system are also well defined and this is the environment interface that Ember implements. So if you implement these handful of methods then you're also gonna be good. So the Ember system is built by implementing the environment which has some number of hooks here and I'm pretty excited to see people experiment with alternative hosts for the glimmer system that for example might lean more heavily on immutable models or RxJS or whatever interesting technology people are excited about and want to explore more thoroughly. One of the greatest strengths of glimmer in general is that its primitives are simple enough and powerful enough to allow people to model all kinds of data abstractions and mix and match them if they need to instead of being sort of forced into a particular paradigm and I'm excited to see what people do with it. All right, so you can take a deep breath again. We're done with the technical part but before we wrap up there are some people I would like to thank. So all of these glimmer two work once again would not be possible if Tilder and LinkedIn were not sponsoring for a time but that's not it. A few weeks ago I wrote like I spent a few hours I wrote this very long, Quest, Ezio and GitHub outlining a lot of the work that we, a lot of the ground work that we still have to do to get glimmer two shipped in Ember and the time I honestly wasn't sure if this is gonna be a good use of time because it's pretty close to EmberCon. We have a lot of work to do and this like took an entire afternoon to write and I'm not sure if people will read it but the Ember community has proved me wrong. Just a few hours later after this Quest issue was post over the weekend we have received many, many poor requests flying in from people to the point that now there are too many poor requests waiting for me to review and that's very awesome and particular Chad and Gavin has paved the way to porting a lot of these new tests and for example, Robert on the core team has landed the actual feature flag that allows you to enable this on your app. A lot of contributors, a lot of new contributors that have never contributed to Ember before has responded to call for help and opened multiple poor requests to help with this effort but that's not even it because we couldn't have built Ember glimmer two without glimmer one with HTML bars without handle bars and all the work that have paved the way to here. So a lot of contributors have paved the way for us and that got us here today and based on what you could have just talked about I think the future here is pretty bright for us and I just wanna say thank you everyone for being an awesome community member and yeah, thank you for being awesome. Thank you very much. We've actually, there are two more things. Speaking of thank you. I was just saying thank you to the community. Okay, thank you to the community. You should actually give yourself a round of applause. Speaking of thanking someone, the other day Leah told me someone made these stickers for me and thought they were pretty awesome but I don't know who made them so I don't know who to thank and this secret person also dropped me some more stickers here so if you know who this person is or if you know how I can get more of them because everyone wants them please come talk to me afterwards and there is, or I have some stickers here so if you want them you can come ask for them after the talk and finally there's one more thing. So three or more months ago, six, well I don't know, Leah will say it's like a year of time, we started, we had a good idea for a swag item at EmberConf and we actually did a lot of work and we thought we were definitely gonna get it by yesterday but for a whole bunch of comedy of errors we didn't end up arriving on time but we didn't give up, Leah spent hours on the phone with various people and these things are here. We don't wanna give up on getting them. We have a special final swag item for those of you who have made it through to the near end of the conference so here is the swag item. There are three different bus toys everyone gets just one. If you stop by the registration desk before 620, the selection is random, you get whatever staff member grabs head of the bag and unfortunately you don't get to choose. Please don't stop at the lines trying to negotiate, trading is encouraged and if you want to complete your collection you can buy them at the DevSweck table until they run out. Thank you very much.