 Hello, everybody. Yes, it's me again. Prepare for more bugs. I'm kind of excited to be here because we finally reached a point where with Houdini, I can talk about actual APIs because they're starting to land. And that's kind of really exciting. But as with any talk, I kind of have to start with what Houdini is. Because on my Twitter, I often see there's still confusion because it turns out there's a software called Houdini. There is apparently a magician that was called Houdini. So I kind of want to clear up what Houdini really is about. So every browser has more or less four major stages in the rendering pipeline. It starts with styles, where the browser collects all the styles that are in the document, and then figures out which element is affected by which of these styles. And now we know with the height and if it's flexbox or grids, which style is on which element we can do layout. We can basically calculate how big an element is and align them on the page and get boxes on the page. They're still empty and transparent because in the next stage, we can take that layout page and paint it. Just draw it. And we can draw it all on the page. Sometimes elements get on their own piece of paper, which is called a layer. And once we're done painting, respecting things like background color and the text color and the border color, we can give all of that, all these pieces of paper to the compositor and put them together into the page that you will see on your screen. And if something was on its own layer, we can move the pieces of paper around, and that's how animations are made. I mean, that's obviously kind of a shortcut, but you can kind of see where I'm coming from. So bringing it back to the question, what really is Houdini? Well, Houdini is a standards effort in the CSS working group in the W3C to expose hooks into these major stages of the layout phase to the developer, to you. So you have more control not only over the visuals, but to write better polyfills and have more control over how your page just appears to the user. It is hard because these four stages are different in every browser. Sometimes they're even parallel or not even that clearly separated. But we're working with all the browsers to make sure everybody can implement these APIs. Houdini can be super intimidating at first, because under the Houdini umbrella, there's a lot of APIs. And you don't really immediately know what to do with what. But they actually kind of form a hierarchy. So you have four high-level APIs for major APIs that basically represent those four major stages of the rendering pipeline. And then you have a couple of lower-level APIs that build the underpinning the basis for Houdini and that make these higher-level APIs possible in the first place. And specifically, workloads are really interesting. Worklets are kind of the Swiss army knife within Houdini for performance. And so I want to make sure I take a second to explain these, because we're going to use them for the rest of the talk. And more importantly, I want to distinguish them from workers, because lots of people confuse these two. And I can blame them because they sound very similar. And in fact, they actually have a lot of overlap. But there is a couple of very important differences that I want to explain to you. And for that, we have to talk about the event loop. This is an event loop. And if you don't know much about the event loop, that's absolutely fine. Everything that you need to know, I will explain to you today. But if you want to know more, I really recommend watching Jake's talk about the event loop, which you can probably find on YouTube if you just type in his name and event loop. And actually, I'm using a lot of his visuals in this talk. So this is an event loop. It's a loop, and it processes events, and it's called an event loop. Whenever an event happens, the JavaScript engine checks if there's a handler for this event in your code base and then takes the code for that handler and queues it up. And every turn, the event loop takes something out of the queue and runs it. And then in the next turn, it takes the next thing out of the queue and runs it. And that's obviously super simplified, and there's much more nuance to this entire thing. But that's kind of how an event loop works. And in this world, a worker would look like this. It's a completely separate event loop. It's an isolated scope. It has its own handlers, its own events, and they have nothing to do with each other. They might be able to put a task into the other loops queue with post message, but that's pretty much it. And there is considerable cost to spinning up and maintaining an event loop. And that's why you can't just spin up 1,000 workers and call it a day, because that's actually quite costly. Worklets are different. They're also isolated JavaScript code and with their own scope. But worklets don't have an event loop. Instead, they kind of attach to already existing event loops. And that makes them a lot cheaper to create and maintain. You can even attach multiple worklets to an already existing event loop. And because most worklets are specified to be stateless, we can even migrate them in the middle of their lifetime. So if it makes more sense for your code to run in sync with another event loop, we can just take it off and take it to the next event loop where it makes more sense. So this will come in really handy later on, but that's basically the big difference between those two. And now that we have worklets in our back pocket, we can finally talk about the very first Houdini API, which is for the paint worklets. So as I said, I'm not going to go through these in order, by the way, more like in order of availability, if that makes sense. But for the paint worklets, the API is called the CSS Paint API. And as I said, all elements have to be painted sooner later to be able to appear on screen. And so far, you have been able to use CSS to customize how your elements appear on screen, but only with those ways that CSS exposes. So for example, if you want to do rounded corners, you can reuse border radius, and you get this, and it's kind of great. But it also turns out that there's different ways to make a box seem like it has rounded corners. And if you want to use any of these other ways, you're kind of screwed nowadays because what do you do? So for example, there's a so-called squarkle, which mathematically speaking, is closer to a circle than a square, and it doesn't change curvature abruptly at all. So it has a kind of different aesthetic look, which could be kind of nice. So if you wanted to have this thing on the web today, what do you do? You can maybe do an SVG background image, which is not really a border. You could maybe use a canvas or nine slice image, I don't know. But with Houdini, you can actually teach CSS how to draw the exact look that you want to have on your page. So how does this work? Step one with all workloads is that you have to load a JavaScript file into the workload that the browser gives to you. So in this case, we have the CSS namespace, and all the workloads that Houdini brings to the browser are going to be in the CSS namespace sooner or later. So in this case, it's called paintworklet, and every workload has an add module call with which you can load a JavaScript file into that workload. So let's take a look inside this file. In that file, we want to teach CSS how to paint something new with JavaScript. But first, it needs a name. So there is a registerPaint function, and it takes a class. And now we want to basically associate a name with that class. And every paint class, in this case, I'm using my paint, we need to define a paint call. And this paint call gets a context, which is almost identical to the canvas contact that you're hopefully familiar with, a geometry object, which tells you how much width and height the element has that you're supposed to paint, and a properties object, which allows you to read the styles of the object that you're painting. So like background color, text color, font size, all these things are in there for you to read. And now what I'm doing here is basically I'm setting my full style to hot pink and just draw the biggest possible circle in the middle of the element. Not very useful, but in the way useful for me to show you what is actually going on. So now that we have defined how to draw this appearance, how do we tell the browser to actually use this new appearance? So we do that in CSS. So in this case, I'm just setting a new style. And you can use paint workloads everywhere that CSS expects an image. So in this case, I'm setting the background image not to a URL, but to a paint, and use the name that I use and registerPaint in here. So here I use paint, my paint. And this is actually, if it works, no, this is not good. I told you, prepare for my bugs. No, the entire laptop froze. No. OK, maybe it's coming back to life. I'm going to try something. I achieved something today. All right, as I was saying, we load the file, we had that. We had this one. We draw a circle in the middle. And I want to do the big reveal, where we use the paint function for the background image instead of just a normal SVG image. I'm going to press the button. We have a pink circle. I'm so happy. By the way, everyone, thank you so much for the kind messages on Twitter and your support here in the room. It could have been so much worse. Thank you very much. What I'm doing here is, as I said, I set the background image on a text area. So this is a text area where I'm animating within height. Don't do this at home, kids. Never animate within height. But you can see the circle is pink and in the middle. So you might be asking, what is the advantage of using Houdini's Paint API, what this talk is about, over using a normal canvas? So there's a couple of things I want to talk about. The first one is auto-repaint, meaning that the browser can figure out when it actually needs to run your code to do these painting operations. I'm going to talk about this more a little bit later in the talk. It is auto-sized. If you've ever worked with the HTML canvas, you know that the number of pixels on an HTML canvas is completely independent from the number of pixels a canvas has on the screen, which is super painful to work with. And in this case, you don't have to worry about it, because it is automatically set to the correct size. It is off main thread, meaning the code that you write to do the paint operation doesn't run on the main thread. And that's a lie. Currently in Chrome, we do run it on the main thread. But as I said, the workloads can be migrated. So the second we have the infrastructure in place to run this kind of code somewhere else, it will just happen. And that means you don't use any of your main thread budget, making sure your page is buttery smooth. No DOM overhead. And this one is actually very underrated. Often I see effects on the web that use a couple of DOM elements or any kind of assembly of different styles to achieve a certain visual effect. With this, you're just using a virtual canvas, so not even one DOM element to achieve this effect. And that can really add up on low-end phones. So for example, this is one of the no, no, wait. For me, this just means I'm going to skip that slide. So what I'm going to do is I'm going to go out of full screen and moving this to a different slide. I'm going to back into full screen. And we're going to go to this one. All right. My point that I was trying to make was that we found that on low-end devices implementing these kind of effects, like this wonderful effect that Una implemented, is actually more efficient in the paint workload than using a million DOM elements. So that's why this is actually a performance formative to make your app run buttery smooth even on the low-end devices. This is another fact that Una wrote that I think is really nice. And this is kind of a nice example to show how the browser can decide when to paint and when not to paint. So in the paint class, you can declare your dependencies. You can say these are the CSS properties that I rely on. And so the browser knows only when any of these properties change will the code have to run, otherwise it won't. And so in this case, you have a couple of custom properties saying, I want to have this number of stars, and this hue, and this different sizes kind of thing. And then in case that I just do a keyframe animation on the hue, and you end up with this effect. And it's actually efficient in the sense it doesn't run just a RAF every frame, but only repaints when the animation actually tells you it is necessary. This is another fact, a simple clock that many people might write with SVG or with a canvas. Some people would, again, probably bend over backwards and try to make this happen with a DOM and just a couple of DOM elements. But if you look closely, you can see that the hand actually has a trail, and that suddenly makes it a lot harder to do with SVG or with a DOM, and maybe canvas would be more appropriate. The nice thing here is that you can have this module, a clock CSS Houdini module, and configured with just a couple of custom properties. So you can animate the background color or the color of the hand, the thickness of the hand, the thickness of the circle at the end, or the length. You can show or not show the individual stops on the clock. You could do all of these things at once, but it gets really stressful to look at. So I wouldn't do that, but it's just a clock. And once again, this trail is just a CSS transition. So the browser knows, while the transition is going on, I need to repaint this every frame. But the second the trail is done, it stops repainting. It's a really easy performance win. So far, we've been using CSS paint for background images. And we have gotten pretty far, I think, if you still remember what I was talking about a couple of hours ago, it feels like. But you can use it anywhere with CSS Expectation Image. So for example, you could also use it for a mask image or a border image. So in the land of border image, you could make this kind of organic look, where the border looks kind of hand drawn. And if you want that kind of look, CSS paint makes it really easy to achieve that effect. This is probably very important progressive enhancements. You can detect support for paint work in both JavaScript and in CSS. One note about the ad syntax for ad supports, it detects support for paint worklet, not for one specific paint worklet. So even if the name, like in this case something, doesn't actually exist as a paint worklet, it will still get evaluated, which is kind of handy. For this talk, I want to introduce the three-pix stability index, which is supposed to be a little notion of how stable an API is based on the story of the three-pix and the wolf who tries to blow their house down. So in this case, in the CSS paint API, the spec is a candidate recommendation, which is basically W3C speak for it's stable. It's shipped to stable in Chrome. Safari announced that they have it in development right now. And with that, I will call it brick stability. At the bottom, by the way, is supposed to be a brick emoji. But the brick emoji just got standardized in June of this year, so none of the funds have it yet. But luckily, it still kind of looks like a brick. If you want to know more about this API, I'm going to shamelessly self-block the article that I wrote, which you can find here. If you have any questions, hit me up any time. And with that out the way, we finally have talked about the first Houdini API. And I'm going to can go on to the next one and see if the browser will handle this. I just realized I, should I risk hiding the Euro elbow? I will do it. Good. The next one, compositing. As I said, the compositor, main job is to do animations with the papers that move around. So as such, the animation is called the Animation Worklit API. So let's talk about that a bit. If you currently think about animations on the web, you have three choices. It's more like two and a half choices. You have CSS transitions, which allow you to transition a CSS property from the current value to a new value. You have CSS keyframe animations, which are a declarative timeline API, which is more powerful and can do some kind of looping. And you have the web animations API, which is the imperative version that allows you to do nested timelines and all kinds of sorts of things. But the problem is that it's really badly supported. It's behind the flag in Safari. Chrome has an implementation, but it's missing a lot of features. Edge doesn't have it at all. So it really isn't usually a good choice. But even if it was, there are often scenarios where what web animations API offers is not enough. And this is where Animation Worklit API would come in. So what you see here is a normal web animations API animation. It would usually web animations API is thought about in the .animate call. This is the same thing, just a little bit more elaborate. It's also part of the API. And a Worklit animation is actually very, very similar. So for example, I would just use a Worklit animation for an animation. And because we are associating this animation with a Worklit, we need to once again provide a Worklit name. Other than that, it stays the same. So we have a keyframe effect that we target an element with, and we have two keyframes that we want to use within two seconds. Then now we have an animation Worklit on the CSS namespace and can call addModule. And now within our animation file, we can use JavaScript. We have an animate callback where we get the current time and the effect of the animation. And now it's our job to set the local time of the effect, depending on the current time. If we do it like this, where we don't think about it, it's literally a pass-through, and it will behave just like a normal web animation API. But this is JavaScript. So you can basically implement arbitrarily complex time mappings. Now what does this actually mean? I'm not going to go into all the details of this API, but just going to give you a little taste of it. So if you want to know more, I'm going to shamelessly self-like another article I wrote, which you can find here. And again, read it and give me feedback. I would very much welcome that. But what do you use animation Worklit for? So for example, I think a year ago or two years ago, Safari proposed the spring timing function. And it's implemented in Safari. I don't think any other browser has implemented it so far. But what do you do if you want to use it? Or what do you do if you have any other timing function that doesn't exist and you want to use it? This is where animation Worklit would come in handy. So in this case, we can, for example, write a bounce animator. Because if you think about it, if you animate an element from A to B, you can either just move it from A to B. But you could also move from A to B and a little bit back and a little bit less back. And it will look kind of like a bounce. And that's exactly what we're going to do. So we have a constructor where we take some options. In this case, that's going to be an option, for example, for bounciness, which makes sense. How bouncy is it supposed to look? And in the animate call, we're going to use this bounce function to, depending on the bounciness and the current time, we're going to determine where in between these two keyframes we want to end up. So the bounce function I use, I implement it with some really dodgy and hand-wavy physics. But in the end, you can just think about it by implementing this kind of graph between two keyframes. So if we do that and we run that, you can see that it's now actually a bounce. And keep in mind that this is literally just two keyframes, and we're just bending time, so to speak. And this animation, because it's a workload, runs off the main thread. It actually runs on the compositor thread, meaning that even if the main thread is super busy, it will make sure that this animation runs exactly at the device's frame rate, frame perfect, and make sure that your animations look really, really smooth. So so far, we have done this. We have done an animation. But if you look at this, I explicitly wrote out document timeline, even though it's an optional argument. The point is that with animation workload, you could get time from somewhere else, not just actual time. You could, for example, think of something like a scroll timeline, or you could even conceive something like an input timeline. We are talking about input timeline, but I have nothing to show here, but I can show you scroll timeline. So here you see a Pac-Man that I have linked to a scroller at the bottom. So what you see, I can basically scroll the scroller at the bottom, and the animation will jump to the position where I am within the scroller. And so it kind of gives you an animation scrubber. And this is kind of fun, but not that useful. But you can conceive of more useful users for the fold. Scroll linked effects, where I have three independent animations. The follow button, my name, and my avatar are all scroll linked effects that can assume their position within the animation, depending on how far I scroll. The parallax effect would be another very popular choice to do to use with this. And it's much easier to implement than it currently is on the web. Now, in combination with CSS scrubs, CSS scroll snap points that we just implemented in Chrome, you can now have a lot of synergy here, where you have really smooth transitions between different sections of your app. And you see like an indicator in top, and the images kind of zoom into view. And now for me, the really interesting thing is that animation rocket is the same thing as the paint rocket was for rounded corners. If you don't like how scroll snap points work, animation rocket is low level enough to allow you to implement your own version. So it really future-proofs the web for whatever people will come up with in the future. Let's talk about the three-pixability index for this API, which we have gone through many, many iterations on animation rocket, but always in collaboration with Apple, with Microsoft, and with Mozilla. And we are now at a point where we feel fairly confident that all the browsers are at least on board on a conceptual level with what we come up with. So all in all, I would give this a wood stability. As I said, we feel pretty confident about it, but now it's really time for us to see what you feel about it. So it is in Canary, you can play with it now. And we're going to an origin trial in Chrome 71. So if you wanna test out in production, and we would love it if you do, please sign up here. As I said, the article should give you all the insight that you need to get started. And if not, please contact me. I'm very eager to help out so that we can get some real data on the benefits of animation rockets. I have, I don't know how much time I have left at this point. I'm just gonna go for it because I can talk a little bit about Layout API. So the Layout API, I'm gonna start with the three-pixability index because it's complete straw. Like we literally refactored this API two weeks ago at TPAC. So there is like a half-finished implementation in Canary and you should play with it, but don't expect the code to still run next week. But there's so much potential in this edit, I really wanna give you like a little insight into this. So with the Custom Layout API or the Layout Worklets, you can basically define your own display values. So I'm just gonna have a main element and a couple of divs in there and that's it, all the other magic will happen in the Worklets. So now we have a Layout Worklet on the CSS namespace. I'm gonna add the module and in there we have a Layout Callback. I'm not gonna explain all the parameters because A, I don't understand them all and B, Layout is pretty complex. But I'm gonna keep this one simple so we can get a feel for it. So what I'm gonna do is I'm just gonna loop over all the children on my child nodes that are on my Custom Layout element. I'm gonna lay them out in empty space basically asking how big would you be if you had no constraints and then I'm just gonna give them a random offset, basically giving them a random position within the rectangle that I occupy. And then I return this list to the browser saying, I did my layout, now please go forth and paint me. And that's exactly what the browser will do. So if you look at this, you can see a couple of rectangles and every couple seconds I add or remove a rectangle to force a relay out and they get a truly random position which is also truly useless. But you can see that this is actual the layout phase of the browser. This runs during the layout phase of the browser, something that was completely closed off to developers so far. And to give a little more of a useful example, I also implemented a masonry layout. So here I'm just loading random images from unsplash with different aspect ratios and the masonry algorithm, if you will, takes care of assembling these in three columns. And the number of columns is once again just the custom properties which I can increase and it will kind of scale up and give you this really nice masonry look which so far you would always have to do with position absolute magic and main thread JavaScript and this is just actual layout which I think is really exciting. If you're interested in the code because I don't have an article for layout work like yet mostly because by the time I would be done with an article it would be out of date again. Please go to this repository that I maintain where I have samples for all the work that I talked about today and you can fork them and play around with them or I would be so happy if you contributed to them. I kind of want to build a collection of the shelf Houdini elements with popular effects which I think are really useful. If you want to keep up with the development of Houdini, I made ishoudinireadyget.com where you can see all the browsers which Houdini APIs they support, which ones are in development, which ones they at least want to implement in time. There is links to the articles, to demos, to the specs. Hopefully I can make this like the one stop shop that you need to keep up with Houdini and I can't believe that I made it to my last slide.