Speeding Up Your React App With Less JavaScript with Miško Hevery === Paul: [00:00:00] Hi there and welcome to Pod Rocket, a web development podcast brought to you by Log Rocket. Log Rocket helps software teams improve user experience with session replay, error tracking, and product analytics. Try for free@rolllogrocket.com today. I'm Paul and joined with us is Mishko Heery returning once again Mishko is the CTO of builder.io and beyond that he's also the creator of Angular and Quick. And today's podcast, we're gonna be talking about his recent talk at React Summit 2023. Speeding up your React app with Les JavaScript. Welcome back. Misko: Thanks for having me again. Paul: So last time you were on the podcast, we were talking about Quick, we were talking about Resum ability and we were talking about some of the other frameworks that you have created. Angular was that the first big project? , the first framework that you stepped into creating? Misko: It wasn't the first framework I were, there were a few before that, that nobody has ever heard of and, it never really made [00:01:00] public, et cetera. It was internal, et cetera. But it's the first one that kind of Was made public and did take off. Paul: So you got into angular and then quick. So maybe some of the ideas that were in Angular, you wanted to revise in quick, but the big poster child, every time you. Search up quick on Google is Resum ability and it's like a different idea about how we're hydrating or, I don't even want to use that cuz it's hydrating. Might be a misnomer for how you're making the magic happen. Before we get into quick, what is builder.io because this is really a fantastic thing that you and the team have put out. For folks that are listening who don't know what it is, Misko: So it's a headless visual cms. And I think I, I feel like those words don't mean anything, so lemme just dive into them. So, Headless is a designation that industry uses, meaning that it's a CMS that , you integrate it with your own infrastructure. In other words, you have your own application, the written Angular, react Quick, or any other framework that's popular, and then you integrate the [00:02:00] CMS in it. This is in contrast to. Host it, which would be like Wix or some other page builders where you're like hosting on somebody's else's infrastructure. So headless means that it's part of your own infrastructure. And visual means that it's drag and drop tool where you can take your components that you've created, let's say an angular reactor quick, and you can drag and drag them into the ui. And this is important because it allows Non-developers, creative folks like marketing, et cetera, to be able to go and edit the homepage without really bugging the developers. Paul: And that's a magical experience to be able to take like a custom component, something that you control, you own. then give that front end experience that drag and drop. I've perused the builder.io videos online and the website, and it looks so exciting to kind of like, oh, I could get my friends who are designers and my friends who are engineers and have them meet with this medium. I'm curious if you're running a team or you're an engineering managers or CTO in that position, trying to make that choice, [00:03:00] how do you think that technology, putting builder.io in that puzzle piece, position changes? A traditional team infrastructure. Misko: I, I think it changes it very nicely. If you look at traditional ways of doing this you have a lot of headless CMSs, but , the way they work is that they allow the developer to basically create a binding that's controlled by the marketing folk, right? And so the marketing person is oh, I wanna change the title. Great. Change this value, right? But I wanna now make two titles. You can't do that because, I haven't implemented it. So now the marketing person has to go to the engineer and be like, Hey, can I have two titles, please? And so now you put it on your engineering backlog and at some point you get to it and a few weeks later you say, here now. Yeah, now you can have two titles. And then the marketing person says, great. But now I want the first title to be different color than the second title. And it's it's this never ending. Back and forth between an engineer and a marketing person. And the last thing the engineer really wants to do is to do these kinds of changes to the system. It's boring. That's not really exciting. And so the [00:04:00] exciting thing about Builder is that it allows the engineer to do what they enjoy, which is build up new components, and it allows the marketing person to do what they, find value in, which is like AB test and try different experiments and schedule things for specific time of day or month or, whenever the sales happens to be. And so it, it's a way of allowing each subcategory of people who are building a product to do, be their best and not really have dependencies. So a tool like Builder IO is really about removing dependencies between folks so that the marketing folks can. Go and change the ui change complicated things about a ui, like the layouts or number of things on a page, et cetera, without constantly having to ask engineers to do that. And of course, like engineers don't wanna do this work anyways because it's not, what they enjoy anyway. Uh,. So I think it's a, it's best for both worlds. So I, I think the way we think about it is that we remove friction between the two groups. Paul: And I, I feel like that sort of [00:05:00] like piece you noted about how, oh, engineers don't want to do this marketing or design piece, that isn't always true. I would assume, there are engineers out there who love to design and stuff, but , there's a lot of like CRUT that gets removed about every product that gets designed because. I know I've been stuck in a Figma session where I'm just like, why am I here? I don't care how you guys are putting this together, cuz you're gonna change it next week. Misko: I think maybe I should revise that statement. It's not that the engineer is not enjoying maybe marketing problems, I'm sure they, that many engineers do. It's more like the kind of changes you end up doing, right? You wanna do meaningful change rather than. Oh, now I have to create an extra binding so that the font height can control, some value in the database can control the font height of it, right? Even if you enjoy marketing, that's not the thing that you wanna work on as an engineer, right? You wanna either do something complicated or something, that requires a lot of thought, et cetera. That's how you get, The joy out of it, right? And so the point is that the simple stuff that. [00:06:00] Oftentimes needs to be done in order to enable all these things. Those things can disappear from both sides of work list. So the engineer doesn't have to do them, and it doesn't mean the marketing has to do them either. The tool does it for you. Paul: I find sometimes if a body of developers are about to embark on making the homepage and sketching stuff out, they can get stuck on Oh no, this should go to the left and this should go to the right and I like this color and I like that color in the sense of the team infrastructure question that I kind asked when we stepped into this conversation. Do you think that builder removes a lot of that anxiety when you're embarking on a project, or is it, do you, do engineers have the sense of I just need to make a really good like component system and then hand that off? Misko: I think it's nice to be able to separate, right? Like right now I am building a component and then right now I am designing a page. And I think you wanna keep 'em separate rather than doing it everything all at once. I think it's a different part of the brain that has to be involved in it. And, some engineers are good at making things look good. , I happen to not be one of them though. [00:07:00] But I think having the right tool for the job, I think is important. So when you are tweaking the layout, the look and feel, et cetera of the page, it is so much nicer to be inside of a responsive editor, visual editor rather than be inside of, a CSS code and fight with how many open and closed braces you have to get and what selector you have to deal with. So I think it's a different time. In, in the life cycle of a product, and I think that's what the tool allows you to do, to have the best tool from the job at the right moment. Paul: The best tool for the job at the right moment, and I think. That mantra really is a good thing for us to segue into talking about Quick and talking about Resum ability, talking about React Summit. Before we do that, cuz we're at our, a bit about Midway point here, I just wanna remind our listeners that the podcast is brought to you by Log Rocket and so on the topic of trying to reduce friction between your teams, if you have a. Web development team and your QA team and your design team, and you wanna drill down to your [00:08:00] app and find bugs faster. You can use Log Rocket to just drop it on your page. You can find events and insights that are brought up so you can spend more time building and less time debugging. So head over to log rocket.com and try it for free today. So Mishko quick is, One of those things that we can say is the right tool for the right time. Because there's a bunch of tools coming out in this day and age in the web development world that have to do with the way you bring JavaScript to the client. Like, how are we rendering, how are we pushing out updates? And at React Summit you were you gave this interesting stance I would guess, which is like hydration is a workaround. And let's start with that. , what is hydration and why is it a workaround? Why is it not a solution an A-list solution in your head? Misko: Yeah, I think it depends on, you have to look at the history of how we got here, right? So originally we started with client server kinda architectures, and we were. Composing things on a server, [00:09:00] and then we needed to bring high interactivity to the client. And so we would do PHP on a server and we would do jQuery on the client. And the problem with this model is that there are two different languages that you have to deal with, right? And so it's not the best development experience, right? It's not a knockout on any particular language you choose. In the backend and a not a knock on the particular framework you choose on the client. Rather, it's the fact that there are two separate things, two different mental models, two different ways of doing things, right? And so, the reason my client side rendering took off, I think is because you could just have your whole mental model in a single place, right? You could just say Hey, I just have one language to deal with, one framework to deal with, one way to think about the problem. And therefore it's a simpler way of developing. The thing that people notice is that, hey, This is great. The client side rendering is a really nice developer experience. But on the client I have to wait several seconds before the page comes up. I'm basically staring at a white page and then the white page eventually I. Turns into the application and I can [00:10:00] interact with it. And it also means that , on the client, huge amounts of JavaScript has to be present before you can render that initial page. And so people, were looking for a solution. And the solution that people chose is this idea of service site parenting. In other words, instead of having you stare at a blank page, how about we show you the actual application? But it's really static. It's not interactive. And then we still do the normal thing, which is we still go and rendered whole application on a client. And so by looking at a picture of something it makes the time go quicker because you're like, oh, I can start thinking about what I wanna do and hopefully the page is up and ready before I'm ready to interact with it. Now this kind of mental model is improved slightly by saying how about instead of throwing away the old html, we just reuse it, reuse the dom. So we have reconciliation and this is basically what became known as hydration and. The trouble with hydration is that it doesn't actually make the app go faster, right? It appears to make the app go faster. Cause you show the user something, but it doesn't [00:11:00] actually make the app go faster. And the other way to think about it is you run the app twice. You render once on a server to render the page, and then you run everything again on the client because you wanna make sure the client gets the same state as the server was at the time of rendering Paul: , if you're saying it has to do this reconciliation, , of course it wouldn't make the app go faster cuz there's more things that the app needs to do now. Misko: Yes. Paul: a, is that a naive way for me to digest that? Misko: No, that is correct. Like it the reconciliation, you could argue that reconciliation is faster because you don't have to create dom noes, or you could make an argument that oh, well it's still slower because. More HTML showed up, like the more bites on the wire had to come up. I think in practice it's about the wash, but like it is slower in a sense that it's not any faster than a regular client side render page, right? It's just that it has these illusion of appearing faster and because it does everything on the client even if you have suicide pre rendering, right? It still does everything on the client. It means that all the has to be present and so, Reasonability is kind [00:12:00] of rethinking of that, like going back in time and saying, Hey, we're already doing all this work on a server. Is there a way to leverage that so we don't have to redo everything on the client? And the goal of reasonability is essentially that when the page shows up on the client, It is fully interactive without any sort of JavaScript execution. And so for, to be able to do that, like Resum ability, needs to have a way of essentially serializing the state of the system. And when people talk about state of the system, they usually mean like the application state, which is true. That's part of it. But I mean, not just the application state, but also the framework State. People don't really think about frameworks having internal state, but they do. The frameworks need to know where the components are, what components to re-render, if some other components state changes, and what are the listeners and what should execute when the listeners click on, right? So all that information has to be present somewhere, and it's really the state of the framework. And so , there's a mobility about this idea of can we execute the application [00:13:00] on a server? Pause it. In other words, serialize everything, go to the client and unpause it. And because we're just un pausing it, there's really nothing to do. We're just ready for the next Dom event to be, next user event, next click, or anything of that sort. And so the result of this is that you end up getting the applications up and running significantly faster with significantly less JavaScripts sent to the client. Paul: So if I may try to wrap the argument about like, why it's a workaround here. Like with hydration the application has some inherent state naturally because you wait for listeners and then you to execute. But at the end of the day, you need to do extra processes to reconcile, you need to do extra processes to ship the JavaScript back. And the idea of resum abilities, you wanna boil it down to the atomic I almost wanna call it the Lambda state, like the atomic point in time, the infinitesimal of this is what the state of the application is. And I guess my follow-up question is are you there? Is theum ability system of quick [00:14:00] able to boil it down to what we would consider as. Developers that atomic point in Misko: Yes. Yes. So that's literally what Resum Mobility and Quick does. And one way to look at it is that if you have a regular application, the way you enter the application is through the main method, right? There's some top level main method that is exported that allows the browser to start execution at that location. And what that does is it starts at the root component and. Recursively walks the render tree and does the reconciliation or rendering or whatever you wanna call it. The thing about mobility is that you flip this whole thing upside down. And the entry point isn't the root component, but rather the entry point is the actual click listener, right? So if you have hundreds of click listeners on a page, which typical page might have all of these need to be possible places where the application may start executing. And , by being able to start at the listener you really speed up. The wake up process for the application, right? Significantly. And more importantly, like [00:15:00] you only have to bring in the code that is necessary for processing that listener, right? So if you have a page, let's say like you're an Amazon and there's a buy button, and you click the buy button the only code that you really need and you have to execute is the listener for the buy button, which probably updates the shopping cart. And then the shopping cart needs to re-render. The fact that the page has a complicated menu system, there's lots of product details and you can go drill down into, different properties of the product or the fact that you have. Reviews from users, all of that stuff is irrelevant to the resum ability of adding an item to the shopping cart. And so by focusing on just the thing that you need to execute in order to add an item to the shopping cart, you've significantly reduced the amount of JavaScript that has to be present, and that needs to be executed on interaction. Paul: And that's sort of the. pinnacle of the point of the talk , that you gave a React Summit is like, the problem is JavaScript. We wanna ship less of it. It's not rocket science. How can we do that? And , I've [00:16:00] tried Astro and these other frameworks that ship zero by default and they have their time and their place and they can be very ergonomic for certain applications. This idea of shipping a resumable component means that by default there might be some JavaScript. No matter what, but it's such a small amount because we're flipping the dom tree upside down. We're starting from the leaves and going up, or am I incorrect in saying that? Misko: So if you wanna compare to Astro, like Astro and Quick ship or about the same amount of JavaScript, right? Because they both have to set up some kind of a global listener that processes these events. In case of a quick, it's about one kilobyte of J JavaScript that be actually in line into the index html. I don't know what it is for Astro, but I would imagine it's somewhere in the same ballpark. It shouldn't be that much of code. The difference I think is that astro, once you interact or once you hover or whatever, you have to hydrate an island. And the island is a whole application. It's just a mini application. So hopefully [00:17:00] the hydration cost of that application is uh, very low. In the case of a quick, you're not really hydrating, you're just executing the listener directly, right? And in case of astro, when you, for example, the menu system becomes visible and Astro decides to hydrate it, you still have to start at the root component of the menu system and then visit every single component inside of the list. Whereas in the case of a quick, you're just literally executing the specific listener, whether it's a mouse move or hover, or click for the menu. And so you get to skip a lot of stuff, Paul: If you're starting from the leaf node and working your way up, how do you prevent disparate in many different executions leading up to different roots within your do. Misko: So we have this thing called an optimizer, or rather we would be, I call it code extraction, right? That the fact that we put dollar signs inside of the source code, right? And the way to think about it is that every time you put a dollar sign, you're basically creating an entry point to the system. You're saying like, this is a possible place where the [00:18:00] execution could start, right? And if you look at it, normal application, The issue is that we don't have enough entry points, right? You really have just one entry point, which is that main method, which I mentioned at the beginning, right? And so by using a code extraction, we can create lots and lots of entry points. So this allows us to enter anywhere. So that's one thing. The second thing is you need to be able to serialize the state in such a way that when you enter through any place, you know that you're gonna end up with a consistent. States so that it doesn't matter which place you enter, or if you enter multiple places or next to it, you don't end up in some weird situation. And so this is the problem of serialization that quick has to solve and it's solvable problem. Paul: And how do you then take these different states? And glue interactivity between what I would in the as world. Consider an island. It's all completely separate application. Misko: Yeah, so Astra definitely has islands. And I think part of the thing that, that people need to understand [00:19:00] where is that once you have islands, you need to solve the problem of inter island communication, right? So if I have an island that is a shopping cart, And I have an island that is the buy button. Then the buy button needs to be able to somehow send the message to the shopping cart and you can say yeah, but I can just do a custom event. Listener. Sure, you could do that, but that means that the shopping cart has to hydrate eagerly because it doesn't know when the event is coming. And so now you're back to like, well, if I'm just eagerly hydrating the shopping cart, what value am I getting out of it? The whole point of this is to do it lazily. And so these problems all are solvable and as an engineer, you can solve that, right? But at some point, like as an engineer, I wanna build an app and I don't want to be solving these weird, esoteric problems or thinking about. Uh, you These issues and I think the value of something like quick is that it gives you a unified mental model of how to think about the application, right? You don't think about oh, there is a button that somehow has to wake up the shopping cart. How do we even know what the correct location for the boundary of the [00:20:00] shopping cart is? None of that stuff really has to enter your mind. Instead, you just build your application as normally. And you let the framework do the magic of breaking everything up into pieces and making sure that the correct code gets fetched at the right time. And that the only thing you really, you have to worry about as a developer is I just need to update the code update the state of the system, and then the shopping cart can re-render. And you don't have to worry about the minutiae of details that have to happen in order to make that ha happen for the user. Right. Paul: In other frameworks and solutions we have the classic server side props. We have what we're talking about now in Astra. We got the boundaries, lazy loadings. When it's in view, you could load the JavaScript. How can we start to think about the quick mental model? If the developer's listening to our podcast today and they're like, alright, I'm gonna go home. I'm gonna try it out. What about their anxiety, about learning something new about a whole new system, a whole new mental model in system state. Can we start to dig into that just for a few minutes? Misko: Yeah, so I think quick tried super hard to make sure that the mental model of [00:21:00] developing your application is consistent with how you've developed applications up until this point, right? So as a developer, you should feel pretty much right at home, especially if you're a React developer, familiar with used methods and hooks. You're gonna come to quick and you're like, Hey. This is essentially the same thing I'm used to. So the magical bit is that quick worked with the existing mental model of how the application get built, but it provides this new way of sending the code to the client so that it has a much better performance for the end user. So as a developer, you really are thinking of it as I'm just building a regular client side rendered application. The interesting thing about Quick is that, What we call is a unified execution model is that you don't really think about whether the code is running on the client or a server. Instead, you're thinking of it as a single unified. Kinda a virtual machine or the code base and you just write your code in this unified execution model. And then a quick through its magic knows how to break this up and decide [00:22:00] okay, this is needs to run on the server, this needs to run on the client and kind of figure out all these things without really any effort on the developer's point of view. In return the devil essentially agrees to couple of constraints. And, these constraints are, you have to use signals because we need reactivity, and we can develop into why that is. And you need to understand the rules around the dollar sign or the code extraction, which basically just comes down to the fact that hey, anything that you close over has to be serializable. And it turns out those are pretty reasonable rules that, once you start using them you'll find 'em very natural and in return, you get this amazing execution model, which allows you to just put code anywhere and it just runs at the right moment doing the right thing for you. Paul: It just sounds too good to be true. Okay, so the two the, the two things, just to summarize, it's the dollar sign code extraction and making sure the code is serializable when it needs to be, or is it All code needs to be all Misko: No it's not necessarily code, it's data, [00:23:00] So , when you read a dollar sign, you might close over , a username or email address or something like that. And all these things are serializable, right? Or you might close over something that might not be serializable like Maybe it's a stream to a database or something like that, right? Like clearly that can't be standardizable. So like you can't do that and you get nice error messages, but people don't usually think of it this way. And also most doubles are kind of already used to this because like when you use something like next Gs, you have get server props, et cetera, around those also have to be serializable, right? So it's not exactly a new thing that you have to learn. It's just something to think about. But it's nice that it's just automatic and you don't really have to think about it most of the time. Paul: On the note of, that boundary between the client and server and things being serializable, there are gonna be people listening who say, I want to take this bubble of JavaScript and force it onto the client. Can we do that with quick? Misko: You can certainly force things to be always on server, and this makes a lot of sense in terms of secrets or, speed or [00:24:00] talk to database or file system or something like that. So there's ways of saying this thing will always run on server. There's not necessarily ways to say always on the client. There are certain methods like use visible task or, click listeners clearly. Those things only make sense within a context of a client, but for the most part, you just don't think about it. You just write code for your application and the right thing will just happen. Paul: Mishko, if people wanted to dig into the docs, what would be the Docs website for quick Misko: quick builder.io. Paul: quick builder.io? Misko: and you can also try quick.new in your browser and that will send you two stack plates where you can start immediately just playing with a page. Paul: Mishko, it has been a pleasure having you on and digging into quick, I love this episode cuz we really got into the nuts and bolts about , some details about observability and the concepts around it, not just what it offers as a product and new concept to developers. If people wanted to keep [00:25:00] up to date with you and your musings and postings, can people find your uh, Twitter? Misko: Yes, I am on Twitter at m Heary and yeah, definitely. I have lots of musings, lots of opinions over there. Paul: Excellent. It was a pleasure, Muko. Thank you for time. Misko: Thanks for having me.