 So I was on the way to the office this morning and I realized it is very much like web depth rush hour Okay, rush hour like all the traffic right everybody trying to get to the office 9 a.m.. Right? So yeah all these people in their cars and on trains everything everyone's just like rushing and nobody can move for anybody else And I think that's like web Because please explain this a bit more because you've got the main thread You've got this one thread and on that main thread. You've got all this work styles JavaScript layout paint composite your frame everything is running and everybody's competing for this one resource the road or in this case The main thread so like mr. Mr. Framework has a car mr. Paint has a car mr. Business logic has a car and they're all just want to go on the road But it's already full exactly and everybody's in the same boat where everybody gets the angry tweets and sees Kind of all this performance advice and nobody knows what to do because all this stuff is just strained into this one place Rush hour as we described in that video. That's kind of how we feel when we look at the web at large We look at it and we go It did all this code should be here, but it just feels like the traffic is the problem like there's just too much going through the main thread and Traditionally you would you know the main thread is full it's overworked and underpaid You would say cool I use threads on any other platform you could do that just spin up a thread put some code there Run it there call a function hooray everyone's happy But turns out JavaScript and the web is special and it is inherently single threaded so you can't do that right exactly It's every thread is kind of this its own little universe. Isn't it like we heard this a v8 isolate, right? Yeah, and so you can't just go just call this on another thread But you've got some shared stuff that you can work on so that's a challenge And then it gets more interesting because say for example, you're trying to build Like a chess game just for argument's sake and you've got a chess engine and the chess engine is It takes a few hundred milliseconds to calculate a move and more. I mean it gets exponentially difficult And you build it with Dom and then some bright spark goes. You know what we should do 3d and you're like I Was already I was already behind on my per budget if you could just not do the 60 frames a second thing That would be great and some even brighter spark says how about VR Yeah, I want to stand on the chessboard. Yeah, I want to be like right in the game and you're thinking there was already rush hour Turns out frame rate quite important when it comes to VR. Yeah, and it could be voice It there's so many things that it could be so this comes increasingly unlike it to for you to be able to do this successfully on the web Currently right and so this is the question that we have been thinking through for the last little while Is there anything we can do anything we can suggest? think of To help we have two birds. We're looking for stone exactly, and oh That went well, okay Wow, I really need to think what I was gonna say next okay this yeah active model yes So we kind of stumbled over this the actor model is as it says right here about 45 years old and it's been Used in or made popular by Erlang and then continues with elixir and ponies There is languages that use the actor model to this day and successfully so and we kind of realized that it's actually a really good fit For the web. Yeah, because what it does is it kind of it makes a feature of that single threadedness of JavaScript But we like to explain if you come across it before Great if you've not come across the active model, we like to explain it in a very specific way So take check this one out. So when we did supercharged you saw us on screen But behind the cameras we had an entire crew and That means we had one person working the camera We had one person worrying about that our audio was good We had a director and each of these people was so responsible for that specific device and instead of going over and pressing One person's buttons or just messing with settings those people actually have to communicate with one another to get the job done If you like their actors in the system But they've got to send messages to one another and communicate and collaborate in order to get the final thing working So that's kind of where more video more production value. It's good, right? So that's where we kind of see a Mentality that fits the web really well and you start thinking about where can you draw a line for individual pieces of Responsibility in your app and instead of thinking about classes and how you call the method on the other class You can now think about these actors and how you can send the right message to request something to happen Right. There's like this areas of ownership. So let's think about how at a conceptual level like how would you think this through? What would it look like a little bit? Okay, so Imagine you have an actor and its job is to run your user interface. That's its area of ownership That's what it does. That's its job and only that You might also have another actor whose job it is is to handle state for your application And yet another one who handles the storage now imagine in your app Typical interaction will be something like favoriting an item The user interface when the user taps on it will send a message over to the state that says this was favorited In turn the actor handling the state will send a message to the storage to say we need to remember that they favorited this item Now we could also at this point introduce a new actor into this story something that could broadcast because when the state changes Typically what we'd want to do is we'd want to send that both the user interface and the storage to be reflect Wait to be reflected in both. I suppose ready. Yes And so you can kind of see here that it really is a separation of concerns I'll click there you go Anvil transition do recommend. Oh, yeah It's really helps you to think about your app in a different way helping you to figure out Where does new code go? Which module can you switch out to fix a problem that you're having? It's a really good way to structure gap in this way. Yeah, absolutely We're used to separation of concerns when we talk about HTML JavaScript and CSS or when we talk about components in a modern framework So it's another version of that same story. I suppose Another benefit that you get and we have heard about this problem a couple of times I think yesterday and today is that we often see big chunks of monolithic JavaScript Just run frameworks updating the virtual DOM and then the DOM or something like that and with this pattern You introduce a natural breaking point where you give the browser a chance to ship a frame because every time you send a message That kind of is a point we say, okay browser can intervene and ship a frame if we are out of frame budget exactly Now a little sort of Side effect a positive one of this is Location independence and we'll come back to this is a sort of repeating refrain that we're going to get into a little bit more but think about actors as They're not all the same. They have different requirements. Some actors Will not need to have access to the main thread for example because of the kind of work they do And as such we might be able to run them in different locations I not on the main thread as I say we'll come back to that but the idea here is Maybe we just bought ourselves a little capacity for rush hour Because as long as the messages get delivered to the actor The actor will then do the same work a bit before and will respond with the same message So the entire app keeps behaving the same way no matter where it runs and because of that location of location independence we can Lower the likelihood of long work impacting the main thread and making your app janky exactly so Conceptually that's what it is, but I think I maybe just does but I like seeing code. I think code helps And so we have We're not launching a product. We're not launching a framework or even a library We just wanted to have a chat with you about architectures and we've been Using some actor based off of the last little while with our colleague tim and the three of us have just been putting some Code together. So what we're going to do is we're going to just show you a little bit of the code that we've been using We've been using it to build some of our apps And we'll share that at the end. Yes, very welcome to try it out You're also very welcome to write your own We don't really care if you use our version or someone else's version It's more about the concept about the architecture. Absolutely So but with this in mind Let's talk about a particular app something like a stopwatch app Which you would sort of start and count up in in seconds Pause play that kind of thing and then you might reset the the time if you're done So in our code, we have This actor based class and that top function up there hookup Is the first thing that you'd need to know and the job of hookup is to kind of register an actor in the system So that we can talk to it later so we can send it messages later on Because ultimately we won't know where this actor is in the system And so we just need a it was like a registry I suppose Where we can say I'm going to tell you there's an actor and it's found under this name It's basically the equivalent of what you might know from custom elements There's custom elements dot define and you say this custom element is now known under this name And this does the exact same thing but for actors Cool. So then we have our two actors a clock one and the ui one And then in the bootstrap we instantiate both our ui And hook it up. So it's available under ui as a string name And then we do the same with the clock Like so So now we can talk about how you might implement something like the clock itself And in our case when you've got something like this, it's a almost like a pure data Actor it doesn't have any need to go near the DOM It just wants to tick and pause and all those kinds of things I mean, what do you need really you need a set interval and that's pretty much it Is it time out? Sure I have a thing against set interval It's a long story come find me after as I'll explain why anyway, um, imagine this then we're going to model this as a state machine What an idea? um We start with a paused state our clock is paused We can transition to a running state Every second we'll tick and we'll go to the tick state and that will take us back to the running state And you can imagine being in this kind of tick running tick running state like under clock like ping-pong like a clock indeed We could pause and we could reset and when we reset We go back to that and that's a really nice pattern here that Plays along well with a message passing of the actor model because all of these Triggers is there called in the state machine world could just be a message you send a message to this state machine It's being ingested and then a transition happens absolutely so So we found actually that there's A lot of implementations for state machines out there in the wild and that's not very unexpected And we've kind of been using x-state which is written by david from microsoft And it's working really well It allows you to declare your state machine as a json object to just declare your states and then what the transitions are And then you kind of just pass this to the this machine constructor and you get a state machine. Yeah, so Our clock extends the actor base class and what we do is we instantiate our state machine We say go to the initial state which happens to be that paused state and then later on Imagine that we receive a message and our actor base class has this on message callback, which is I got a message. What do I do? In this case, we would assume that the state would be changing inside of our state machine So we use the state machine transition to get from wherever it was to wherever it needs to be So the message is basically driving the clock And we'll inspect what the new state value is. So if we find that our clock is running We'll set a tick timeout for one second If we tick we increment our tick count and then the clock will send itself a message Now it could call its own functions, but we tend to be a little bit We like it fair And so what we do is we make sure the clock sends itself a message like every other actor would have to send it a message You can imagine like a message queue that buffers all the message and the actor goes to one message Processes then goes to the next message. And so if you just call your own function It would kind of be cutting that line So if you want to keep it fair, you would just queue your app a message at the end and wait like a good human Exactly or a computer Cancel the tick if you're paused if there's one pending When we reset we'll reset the tick count and again send the clock will send itself a message to pause And now let's talk about oh no talk about sending messages. That's next. Yes So the clock we're going to have to send a state update to the user interface so that it can reflect You know the time going up and so so on and so forth And this is the opposite to the hook up. This is look up Which is also in hook up hook up hook up hook up hook up look up All right, I'll lose him for hours at a time when he does this so okay hook up and look up So we look up the ui And then we can send it a message and that's very important to note here the handle this ui variable that we have there It is not the actor instance. You can't go in and change a member variable of that class It is just an object with a send method and only that method because that's the only way you're allowed to Interact with any of the other actors Exactly And so in this case we're going to send the ui a message and the message is going to say what the time is And whether or not the clock is running We found that typescript is really helpful at this point because those messages need to be well formed and well understood And there needs to be a data contract and we've just found from practical experience that typescript is a really good way of saying This object looks like this. This is a number. This is a string. This is another object and so on and so forth. So Just take that as What it is really we found that yeah recommendation. We found that useful Let's talk about the ui a little bit interestingly You can bring your own framework. Yeah in this model you don't we don't really care what kind of framework you use You can use react you can use view you can use lit you can use Svelte whatever you feel comfortable with or whatever makes sense in your scenario The interesting shift here is that the ui framework is not your base platform Not your entry point anymore the center of the universe has kind of moved Yes, that bootstrap that we showed you i is just one participant of many in the system of actors And if you find that it's not behaving well for whatever reason You can swap it out The only thing it has to do is listen to messages of a particular type which is kind of cool In our case, though, we're going to use preact. Well, it's just great. So we're going to import preact Our ui extends the actor class and when it receives a message We're going to have it render using Preact to the in this case the document body Same again here. We need to send messages back Absolutely and to do that It is a case of the on the ui side We find our clock actor We do a look up on it and we will send it a message in this case for this particular example Sending it a message to start that there'll be one for starpool reset and so on Now we get to talk about that location independence a teeny bit more Because one of the questions that surma tim and I ask ourselves when we're making our actors is does this actor Need access to the main thread And this is kind of to do with the rush hour thing Our general rule of thumb and there are some caveats we'll mention in a moment But our general rule of thumb is that the ui actor is the one that really needs the dom And therefore it's the one that ought to be on the main thread wherever possible There's an exception the exception here is that certain apis those for media security device capabilities and identity are only available on the main thread today We think that's a bug and we've been talking to some chrome engineers about Exposing these kind of apis in a worker and somewhere else, but that's just not the world we live in today So for now, that's a restriction. Yep And tools not rules. So you might be thinking ah, I should move all my actors away from the main thread We'll get to that But the thing is if you've got a really chatty actor that needs to talk to the ui actor You might want to leave it alongside the ui act on the main thread because as jason and shobby We're talking about earlier. There's a cost to the thread hop and that might be more expensive than Just sending a message and just keeping the actor alongside the ui actor Okay, so basically if you want to do that just measure and see what the impact is exactly So the location independence for all that notwithstanding Imagine we were back here where we started with our Four actors and they're all on the main thread, which is probably where we put them by default We're sort of saying you might want to look at it more like this and you might be thinking why do they say not main thread Surely they just meant web workers And we kind of did Because in most cases when we build these apps yet web workers do feature heavily We do move quite a lot of our actors to web workers, especially if they're non chatty But not quite So we actually think or have tried that it's sometimes very very useful to run an actor for example On the server side and this is kind of an interesting jump to make because it allows you To incorporate your back end into the architecture of your entire app It is just another actor in the system and as a matter of fact The game that you've been playing all day and it totally had no bugs at all whatsoever Is actually written in this model. So every player that is playing is an actor the Admin panel that the mcs used to control the app is an actor the presentation view Just another actor and then the firebase storage and shared actor that's running on the server side Now interestingly the the mechanism by which they chat using the hook up and look up can be anything could be fetch It could be a web socket. It really doesn't matter if firebase database Yeah, so long as they can talk these actors can talk and they've got a way of sending messages to one another You're all set. So Back to our original question Did we actually help with rush hour? Would this actually help? Well, let's review So one thing that we definitely did achieve is that we are kind of Making it less likely to have big chunks of uninterruptible javascript and more little chunks where the browser can stop In in between and ship a frame. So that's definitely one advantage that we have the location independence Hopefully some of our actors can be run successfully away from the main thread Hopefully it's like fewer cars on the road at rush hour. That's good for everybody typically And as a result A lot of work that can happen in an unexpected way if you're processing a big api response something That can happen in a worker and not affect your main thread from going into jank mode There are some other benefits that serma tim and I have noticed as well Working in this particular pattern one is better testing With the kind of area of ownership. It's very it's it's easier not always very easy, but it's easier To look at an actor and go well I know what you should do and you've got an on message that I can call And I can make sure that you do the right thing. So the testing seems to become a little bit easier Yeah, or from the other side you can mock another actor by just Implementing the messages that that actually needs to receive and not do the actual work But just send pre-recorded messages back You get the clear separation of concerns Which again, it's just a It helps it helps you in terms of maybe dividing the work with your teammates Or even just deciding for yourself You know, which actor needs to be responsible for this part of the system And you get the code splitting because you have actors That can be hooked up to the system at any point in time really it allows you to split them up and load them lazily You can just import them when you need them. Yep. That's good And bring your own framework if you want to use a particular Library or framework you can this is it's not that you have to there's not a prescriptive way If you want to use some one thing use it great Now there are some considerations In this world in this setup that we've described One is actor performance challenges if you imagine your ui actor imagine it Decides to run long and just be not very yieldy. You still have that problem It's no different to a process or an application in an operating system deciding it's going to hug the cpu, right? I mean, this is this is Not going to go away But we do think that the scheduler api that jason and shubby mentioned in the previous talk Is a huge part of this story because it's a great way for individual actors to start breaking their work up into smaller chunks You may also be sitting there going. I'm not sure I could actorize my blog And we would agree it's not necessarily for all use cases This works really well when you've got apps and in particular apps where you think actually yeah I can I can ring fence. I can mark off particular parts of this application and I can have some kind of owner for it That's where it works really well And there is definitely a different mental model to this as I said there It kind of shifts the center of the universe away from the ui framework into Many center pieces all the actors just communicating so it definitely took us a time to Build an intuition for where do we draw the line? What becomes an actor? What is just part of an already existing actor? What kind of messages should we send how granular should this entire set of b? So if it seems weird at first if you're playing around with this that is kind of to be expected It's a very different way of architecturing a web app So that was the rush hour bit That future facings of like the VR AR and so on Well, we have some thoughts there too. Watch this So you were talking about actors before and I want to talk about cameras And the reason I want to talk about cameras is because it all plays into that story, right? So if you take one of these lenses before I drop it because I don't want it Um You're modeling your modern camera has two bits the camera body Which is the thing that kind of holds the state whether you're shooting in jpeg or raw When it's like the business logic it knows how to take the picture and how to store it and does all that Yep, whether you're shooting video or taking photos whether you are autofocus manual focus you get the idea Similar to like a web app, right? That's the sort of the state of what's going on But you've got different lenses for different tasks. So that one would be something like Portrait lens. This one might be a wide angle. Take something of a landscape Yeah, so we make sure that the mountains are compatible Which I guess in actor work means that they speak with the same messages to each other. Yes So the messages that they send are really important. They're sort of standardized, right? And everybody kind of plays to that same data contract other than that you can do what you like plug it in off you go Last video I promise. Yeah, so camera lenses. Why camera lenses? How does that apply to this story? When we talked about this earlier, I think very naturally We would have all thought of the dom we'd have thought of in the chess game. We'd have thought of this version But there's the freedom that you get from a ui actor That it can so long as it can speak the right messages it can be implemented in different technologies So you could have a different actor that does 3d And now you get that it just has to send the same messages as the dom version the standard dom version Or maybe one for xr Similarly, it needs to be able to do that Send the right messages and perhaps something like voice As well similar kind of story So as a byproduct of the actor model, we've all of a sudden got these different Swappable ui actors that we can take with us wherever we need to go And you might say well actually all I need in this particular app is the xr and voice or maybe I want dom and voice And you could even imagine a setup where you have a dom actor with lots of effects and visuals And one dom actor that implements the same app But with a much less intense memory consumption version like a low end version of your website And once you detect that the device we're running on is actually kind of you know Struggling to keep up You can actually switch it out in the middle of the app and downgrade to the lower visual version Yep, or one with say reduced motion or something like that And technically this would be called multi view or multimodal Which is a very fancy way of saying there's lots of ways to interact with your web app and as a byproduct Um, we think the actor model enables you to do that pretty well So if you're interested in looking at the hookup and look up in the actor base class that we mentioned earlier This would be the place to go if you want to take a snap of that This is actually not only the actor base class, but it's actually a boilerplate So it gets you started that's roll up configured where you can just build it does the code splitting the lazy loading It should get you started really quickly so you can start writing actors and get a feel for how it feels But to be clear, I mean it's experimental It's just the stomping ground that we've been Using for the last little while and we'd love you to take a look and have a chat with us and just tell us what you think Um, so in summary, we're actually quite excited that something from 45 years ago has kind of come full circle And is it's it seems to be You know the thing that respect hiding in plain sight Yeah, and it's you know, it's from some of the places in computing We've kind of brought it over not in a purist way. We have our own take on these things But it respects that single threadiness of JavaScript It seems to help with rush hour and it also seems to enable us to go multimodal, which is really kind of exciting and on that note Thanks. Thank you very much