Kate: Welcome to PodRocket. I'm Kate, the producer of PodRocket. With me hosting today is Noel. Hi Noel. How's it going? Noel: Good, good. How are you, Kate? Kate: Doing well. Thanks for joining us again. And with us as guests today, we have two guests, Ryan Carniato and Dylan Piercey from the MarkoDev Team. Hi guys, how's it going? Dylan Piercey: Doing good. Thanks. Ryan Carniato: Hi. Kate: Thanks for coming on. So, we talked to Dylan about Marko back in February. And we've talked to Ryan about SolidJS back in September. And this episode's a little unique. Because we have invited them both on to talk about web trends and stuff they've seen in this space, and working on the projects that they've been working on. So, I'm excited to see how this goes. So maybe to get started, Dylan, can you just intro yourself again for our listeners if they haven't listened to the episode from February? Dylan Piercey: So, yeah, I'm mostly working on Marko at eBay, which is a framework for building multi-page apps. And at eBay as well we're also heavily involved in the front end ecosystem for the tools that are used there, and various other open source tools as well. I've been working in open source for quite a while before eBay. I've been at eBay for four years. But yeah, that's where I'm at right now. Kate: Awesome. And then yeah, Ryan, can you just give us a little about you, bio here? Ryan Carniato: Yeah. I'm also working at eBay on Marko with Dylan. I'm also the author of SolidJS, a different JavaScript framework. And this has been great, because it's given a lot of perception, standing outward to see different sides of the same coin so to speak. I've been working in open source for several years as well. At my previous startup, I inherited a bunch of open source projects and that's really what got me started with Solid. And then I made my way to the Marko team a few years later. But yeah, I'm really looking forward to discuss how all these pieces play together. Dylan Piercey: Yeah, I can lead in. Because I think the main focus for us, and I think what a lot of conversations that we've been having has been about is really this trend of moving things back to the server. And that manifests in a lot of different ways. But I think it's first important to realize why you would want to move things back to the server and how we got to this point. We're now essentially with SPAs, we've put everything in the browser. We're sending entire applications to the browser. And one of the strengths of the web platform really, is that we have essentially the ability to send mostly completed views to the browser and have minimal business logic sent to the browser. Like if you think of web applications in the past, you could have this giant eCommerce system that essentially just sent you a little page that has all the images and all that stuff. Dylan Piercey: But it didn't send you the whole search functionality, or it didn't send you how to render all of the things. So essentially I view the web as this thin client mechanism. But we've taken it to the extreme now where we've got the entire application being loaded in the browser. So the question is in my mind, how do you get the benefits of being able to have the application in the browser, being able to do all this complex stuff and smooth animations, and all these things while maintaining the performance benefits of what is essentially moving some of the logic over to the server? And I think the web is kind of set up to be in a lot of unique ways, the best platform to deliver experiences like that. And I think we're on the precipice of making that seamless. Ryan Carniato: Yeah. I mean, it's not an easy problem to solve. That's why people have been banging their heads against us for quite a few years now. Because, as you mentioned, we can send this completed view of things. But in order to remake that in the browser, ends up sending all that stuff twice. Actually, a lot of the considerations here is around optimizing for almost duplication actually. When you have a completely serialized view, you send the data twice. Both as the final view, and as the data you need to do work in the browser. You might send the view twice essentially, both as that HTML and as the code to rerender it. And I think almost everything that we've been looking at is, can we save on that bandwidth, and can we save on that execution? And these are really tricky problems that we've been circling around for years. Ryan Carniato: And it's only becoming more and more prevalent of a concern as we've watched the desire for interactivity and being able to do more in the browser only increase. And it makes sense, right? If you want that single experience from a developer's perspective, it is a lot easier to view your experience as one single thing. You just build the app. We saw this in mobile, which is largely what influenced the rise of single page apps in the first place. You just kind of come in, you have everything you need at your fingertips. And it makes the mental model to a certain degree seem easier, at least at first. But then you get all the complexities that come with the fact that you're abstracting away really a client server model. So I think it's an interesting challenge because we keep on shifting a bit. But I think one of the biggest goals in the understanding, at least on the JavaScript side because it's one of the few languages that can actually transcend client server, at least historically. Ryan Carniato: There's new options coming out now with web assembly. But there is this drive for a developer experience where we are maintaining a single thing. And that's why compared to maybe some views of the past where we can optimize things a little easier, because you have a clear backend and front end. Regardless of how many times we circle around this server client thing we're really trying to... I think in a lot of people's mind, trying to find this universal solution, maybe this silver bullet. I don't know it exists, but that seems to be the goal and motivation. And that's driving all of this forward. Noel: I think you answered an interesting question that I had there that would help maybe frame this for people who are coming in from the outside, who haven't been in WebDev for a while. But like of, why did we push all of this to the client in the first place? It almost seems counterintuitive now, like looking back at like, well of course this was maybe not the best path to tread. Dylan Piercey: The way that I've been thinking about it is, a lot like if you're doing something like a remote desktop application, or if you're doing game streaming, or if you're doing even like YouTube and all that stuff, there is so much processing that can happen in the background that makes it so that your device does not have to be as powerful. And the web is really set up to for that. Because you can literally send the HML structure and styles that are able to render a certain part of the view. So, since we already have this great capability to do a bunch of stuff on the server, let's continue to do that. But obviously the draw is, if you can have everything available in the browser, it's easy to add and remove things instantly. Dylan Piercey: And that's kind of the key, I think. The question is, if you want to do something instantly, you don't want to hit a server to do it. And when something's not instant, the user's going to pick up on that. And that obviously becomes even a bigger deal with animations and things like that. If there's an animation that's running, you don't want to hit the server to stream the animation in. I mean maybe if you have a really fast server and it's giving you the full gooey or something like that. But you're going to be able to notice the latency. So the question is how do you make it so that stuff that the server is going to have to do asynchronous processing on anyways happen on the server, or things where it isn't going to necessarily be like... the user isn't going to expect this happens immediately? Dylan Piercey: And even if the user does expect that something happens immediately, how can we opt into progressive enhancement approaches where we can show optimistic updates and things like that? So it's tricky problem. And I think the main issue is that most tools don't really think of this dichotomy, that you can have things that only happen on the server. Some new tools like Remix has been somewhat pioneering, again that you can have loading happen on the server and certain things like that. But I think there is a huge potential for a framework to be able to say like, this part of the application can render around the server versus this other part. Dylan Piercey: One example that comes to mind for me is, if you've got an experience like eBay, where you're searching for a bunch of items, you don't expect all of those items to be available on your machine. There's no way you're going to be able to download all of eBay to your computer. So you're going to have to hit a server in order to get that content. And if you're already asking the server for the content, why not ask the server for that portion of the view as well. Where the server can give you essentially an optimized prerendered part of the application instead of the application having to hit some endpoint and then do the rendering client side. Dylan Piercey: Because now you don't need to send all that rendering logic to the browser which can improve performance. So especially in scenarios where you're going to be doing something async, and essentially you're asking the server for some data. Instead of asking the server for some data, why don't you ask it for some portion of the view? That's one of the areas that I think is super interesting as far as potential futures for frameworks. Ryan Carniato: From my perspective, just going back to the original question for just a second, it came because around the same time that the web got the new capabilities to do ajax and do requests and dynamically update things in the browser, mobile came up, like the iPhone and stuff, mid 2000s, 2005, 2006, around that time period. And they saw almost immediately a huge... especially on mobile devices, where a lot of people live essentially, a huge exodus from the web to just having these better native experiences. And I think that was a really huge push. But I mean, I know it was at Facebook or Meta as they are now. But they really bet hard on the web. And then they're like, "No, no, we do the native thing," because it didn't pan out for them. Ryan Carniato: But the idea here is, the web's always been trying to be this universal agnostic kind of platform. But we saw very quickly that people were going to these mobile apps. And I think there's a bit of envy there. And I think a lot of companies and a lot of experiences really wanted to reproduce that mobile experience. That was like the biggest driver for years. If you go back to 2010, '11, '12, whenever, that's that's what people were always talking about. How to make everything smooth, and how can we get the same affordances? I mean, there's reason for that too. Ryan Carniato: But I think over time it's gone just from the phone to different device sizes, to different things, responsive design. There's been a whole bunch of evolutions in the way we view user interfaces over the same time. And I think there's maybe more flexibility. But we did learn a lot from that time period. And it was very clear that was the trajectory for a while. We wanted a more native like experience, and that kind of got us to where we are. Dylan Piercey: I mean, obviously the reality is, for a while you couldn't build super high fidelity native life experiences in the web. And we're pretty close to actually being able to do that now. But in a lot of cases I think the main issue is, "Okay, now we've delivered this native experience to the web, but these other websites over here that are serving content from the server end up being a lot faster. Why is that? How can we take advantage of that aspect of the web and apply it to these rich experiences?" So there's a ton of optimizations. I think pretty much every framework or most frameworks are interested in some sort of solve for this. Dylan Piercey: We've seen a lot of new tools coming out recently for it. And I think a big part of it is just that, we've now gotten most of the functionality that is necessary to build an actual single page application. So we're kind of rebuilt or rebounding back to the point of, "Okay, well, how do we optimize this application?" And there's obviously this like tried and true history of this is how we've optimized webpages before, and how does that apply now? But it turns out that it's a fairly different model. Dylan Piercey: So it has some frameworks, including Marko and React with their server components. And so when actually rethinking the model and thinking, "How can we bring some of this stuff back to the server?" Because it turns out that in a lot of cases the reason the web was fast, is because some of that processing could happen on our beefy servers with their huge amounts of Ram and CPU. And we could just send the view to the browser or some part the logic to the browser without necessarily having to have everything execute in the browser. Ryan Carniato: Maybe we should talk a little bit what that looks like now. This has been going on for a while. I mean, Marko has been experimenting in this area since the beginning of Marko, that's really why it came about. But in the last couple years, we've started to see others talk about this. And I think if we look at, I guess 2020 sometime, this new term started floating around called islands, so to speak. And I think it's been getting a lot of talk. There's frameworks like Astro, and [Slinkadee 00:13:58], and Aisles. And to a degree, Marko fits in this category, and even React server components. But this is the first stab we've been taking at this. And it's also sometimes known as partial hydration. And I think it's really probably a good place for us to start. Dylan Piercey: Yeah. I think the interesting thing from the island's architecture and partial hydration, is really that it starts with the acknowledgement that there is some amount of content that should only be rendered on the server. It forces you to step back and think that there is a router on the server and you're going to send a page, and then that page is going to have some amount of interactivity. So it does kind of have you step back a little bit from the SPA world. But, within islands on the page, different sections of the page, you can have rich interactivity. And if that's the way that you're building your application, well then everything outside of those islands can be server only. And this comes back to what I was mentioning, where you have the server doing some amount of the work that never needs to happen in the browser. So I see that as the first chip away, the first strategy as a chip away from SPAs, while being able to maintain some aspects of your application, having that like super instant update cycle. Ryan Carniato: Yeah. I mean, Astro has already shown this. I know we've covered Astro on the show before. But they essentially let you bring almost any of your typical single page app frameworks, and stick them in these islands. I mean, the most naïve approach is like, just make you an app and go like, "Here's my app and stick it on the page." But you can do more than that as you break things apart. But there is one big constraint. There is the reason we call these things islands, is because even though there's like the water around them, like the static stuff that never needs to update, they go all the way to the ground so to speak. Once you hit a island of interactivity, basically everything beneath it also needs to be interactive. That's kind of like the baseline. That's why it works. The kind of core functionality or approach to single page apps is a sort of top down rendering approach. Ryan Carniato: You have a root, and then it's your render call when in the browser you've seen it. And then it renders this tree essentially. And what the islands architecture lets you do, is have multiple of those trees on the same page. So now suddenly you have these distinct sections that you're dealing with. And some people might compare it to things like maybe micro frontends or something like that. Because it's basically all these separate independent entry points. But the mechanisms for how we do that are kind of independent. It doesn't necessarily require a separate service or whatnot. So it's not like purely the same as micro frontends. It's more just acknowledging that you have sections of the page that are interactive or stateful than other ones. And the truth is, the smaller you can make those, the more optimal the experience can be made. Ryan Carniato: But you know, the big caveat here is, when your app is no longer a single app you're back in multi-page app zone for the most part. Because while you could update and navigate within any of these islands, once you have it distributed like this, you don't necessarily have a single top bubble orchestration anymore. So usually you're on a page, you load what you need, and then you go to the next page and you load what you need. That's the experience. But I mean, for certain types of sites, categories content site, blog sites, even eCommerce, you get significant savings, because you send way less code. We've observed in the islands architecture. Ryan Carniato: And it's not just us with Marko. It's like 60 to 80, even sometimes a little bit more of bundle size reduction. Just because you don't need to send a bunch of that code. And it also translates to execution savings. Because that code never needed to run. And savings and data serialization. If you are loading data on the server to render parts of your view in those static zones, those areas that are not interactive. Well, the only data you need, because you know it can never change, is the data that enters those top level islands. Basically the top level props that you pass into those components. So that means you can a huge amount of data, render a bunch of static stuff, and then maybe only pass a couple of those properties into those islands. And that's all that needs to be sent to the browser. So in one swoop you have the potential to make huge savings. Ryan Carniato: But, as this islands as we know them today are very much a manual process. You go like, here is the island. And the components don't... once you're in there, you're basically back in that single page app land. And while as I said, this is already a huge savings and we're seeing it, it hasn't quite completed our story. It's not as optimal as we want to make it, a). And we've now kind of given up some of the benefits that we like from our single page apps. And that's why the work doesn't stop there. That's why there's stuff like Marko and Qwik which we haven't talked about yet, but I'm sure we will through the process of this, that are actually trying to push at some other approaches here. And actually React server components deserves a nod too. But that's some other technology and approaches for me to work on here. Dylan Piercey: I think it's interesting to look at the islands architecture. I mean, there's really two things. There's, yes, the islands architecture is good and it has savings and all that stuff. But there's the cons like Ryan mentioned that, as soon as you do have some stage or something like that, something that you want to upload, update at the top level of the application, well now you're sending down basically the entire application and you lose a lot of the benefits of the islands architecture. So the islands architecture really only works if you can force the dynamic parts of your application as low in the tree as possible. And it's not just like moving that logic lower in the tree. It's like making components that have those logic lower in the tree. Dylan Piercey: Because as Ryan said, as soon as one component is opted in to being an island, well, now that entire component's sent to the browser. And I think the reality of most components that people are writing is, there is a ton of static content in there, even though you might have some state that's driving few different sections. If you think about a normal component, maybe you have like a handful of sections that are actually interpolated. Then you've got a whole bunch of divs, and a whole bunch of classes, and a whole bunch of other stuff that's largely static. So one of our questions on the Marko side and what we've been working with on Marko 6 is, how do we break it down further than just like a component level? And so what we've done is essentially go in and look at per component, whether its stateful dependencies which things can actually update, and eliminate everything else. Dylan Piercey: And I think that's one piece of the story, just digging in and making it so that these islands are no longer islands. They're just like the little pieces that actually update. But then the other side of that story on the performance angle, is that if you have any amount of hydration that's happening. And by hydration I mean you're re-executing stuff that the server did in order to get the state built up again in the browser so you can attach event handlers and run that stuff. If you're doing any amount of that work, you're kind of defeating the purpose of the server having done that exact same work. Really the thing is, the ultimate goal is, make it so that the work that the server did does not get redone in the browser, if you can. I mean obviously there's some places where maybe that doesn't make sense. Dylan Piercey: But in general, it seems like that's a pretty feasible goal. And so that's the other piece of what we're doing with Marko 6 is, we're making it so that anything that you render, any data that's calculated on the server, we essentially serialize only the stuff that's necessary for the things that need to run in the browser. Which is like I said, those effects and event handlers. So that's kind of the two angled approach of it. You make it so that you can know how to break up these components into as small of pieces as possible based off of their dependencies. There are other strategies to it as well. Dylan Piercey: Like Qwik essentially breaks things up a little bit more manually. You have to go in and add dollar signs and it can break it up based off of events and stuff like that. But essentially one piece is breaking it up, and the other piece is making sure you're not re-executing stuff. So I think with those two things, and there's a number of approaches to get to that approximation, you've kind of solved the performance issues with islands. But then I think you need to step back and think about what the fundamental issues are, which is navigating between sections and deopting the whole thing. So if you break things up... Oka, I'll let Ryan go. Ryan Carniato: Yeah. It sounds like you were just going to pull right ahead into the next topic. I do want to talk on this for just a moment. Because the framing is good. And I think in terms of just kind of stepping back and for people, is because, people have been hearing terms like islands, and they're familiar with lazy loading and code splitting. And what's happening is, we're actually starting to develop a new vernacular here. There is some new terms and ideas that Dylan just talked about. And for me, it's come down to three kind of... I don't know if I want to call them definitions, but almost qualities of hydration like strategies. Basically there is the first thing which we've been talking about with the islands, which is like the partial part. Like we said partial hydration, how much do we know for certain runs only in the client versus the browser... Or sorry, only on the server versus the browser, and like that split? Ryan Carniato: Then there is the resumability. Which is what Dylan was talking about in terms of execution. To what degree can we not redo work in the browser after you've already done it on the server? And then finally, although this hasn't been the primary concern for Marko, it's one of the ways that Qwik has been doing stuff, is related to that lazy loading. Like how effective are we at shipping less code, how much JavaScript we send, how progressive does it load in? So as I said, they're all related and they're kind of similar. But for me it helps to look at these as almost three different parts of the puzzle. The knowledge of server client, one, the ability to resume or execute less than the browser. And at what degree do we load that JavaScript in? Ryan Carniato: And I think with that kind of framing coming in, it's easier to evaluate these solutions. Because some of these are new ideas. We've been doing progressive stuff in the web for a while with lazy loading. And the partial stuff is this islands thing. But I think this idea of resumability and execution is a newer idea, and it comes a lot from being able to, well, use compilers to be fair. A lot of these capabilities... like you can do partial largely from being manual about it. You can go, here's an island, or you can use a compiler like we're doing Marko 6, to split those things smaller. What we're seeing now is more and more movement to say using compilation to kind of augment. On the progressive side again, you can go lazy load this code. Ryan Carniato: Or, in the case of something like Qwik, maybe the bundler and the automation in terms of compilation can make that smarter. But the third area, the resumability, the execution piece, that one really requires us to unwind the JavaScript code. And that's a large part why we haven't seen these improvements necessarily in existing frameworks. But when you put them all together, what we're talking about actually is the potential to almost eliminate what we consider hydration today. That's the bottom line. I know we talked about a lot of technical stuff. But if you put together what you can see is a world where we send the least amount of JavaScript because we know it runs on the client of the server. We execute only what's necessary and then we load it only as needed. And that's the story here. Because that's very different than the hydration stories that we've been telling thus far. Ryan Carniato: This has been the bottleneck, the uncanny valley, the thing that the Chrome team sends out an article every year to tell us that we're not doing good enough. We are getting close here to solving that. But even if we've mechanically solved it, there's still a lot of work to do to make the developer experience good. And still even with this, we haven't necessarily bridged that gap to single page apps. Which is where Dylan was heading. I just wanted to make sure this was concretely cement of like why we're thinking this way. Because on the optimization side there are solutions. But we're tasked now with actually making those solutions usable and likable, and more so finishing this story that has been going on for years now. Kate: Oh, awesome. Yeah. Thank you for clarifying, Ryan. It's almost like you've been talking about this for the past six months. Dylan Piercey: Yeah. There's a lot to unwind and a lot of different areas that we're looking into as well. It's kind of interesting that it requires... and I think Misko from Qwik has mentioned this on Ryan's stream and stuff like that, that there's so many pieces that have to come together to make this story of continuing where the server left off actually work. But once you can do that, there's just so much less... just thinking about it, the amount less that you have to do. On a single page app, you're downloading the whole application again. You're re-executing the whole application again. You're receiving all of the initial data that was needed to render the application again. So there's just so much obvious duplication, and you can go in and measure pretty much any single page app and see that. Dylan Piercey: And if you can get that to basically zero, which is what these strategies allow you to do, that is huge for especially the first load, but even subsequent loads if you're building a multi-page app. And for eCommerce and why obviously Marko is exploring that, that is our bottom line basically. So it's super important for that. But yeah, then going into the sort of the next thing is like, okay, all of this stuff... as Ryan said solves hydration to a degree. There's a lot of complexity there, but we've hidden as much of it as we can from our users. But the next piece is like, what remains on the developer experience side with any of these kind of solutions? And I think a lot of it has actually been solved, just because of the granularity of this approach. Dylan Piercey: You can now, with this, put some state up higher in the tree. And as long as that state doesn't rerender the entire application, like have it behind an if statement or something like that, it's going to be granular and you're not going to have to worry about your whole application being bundled. But that's where things go south. Is if you do want rerender the application where you have a router in the browser... and that's why we've been talking about making the routing happen on the server. But that does have some limitations obviously. How do you do a transition from page to page in an MPA? And the answer right now is, you can't. Maybe there's specs coming up for transitions across pages and maybe that lands, and maybe that is part of the solution for that specific problem. But in general, we want you to be able to author at this experience where it feels a lot like you're writing an MPA, it seems like a single entry and all that stuff. Ryan's got something to say? Ryan Carniato: Yeah. I mean, the focus on routing is really, really important here. And I think you only have to look at the evolution of the web to understanding how much of an impact it is. We're going to talk a bit here about what we think we can do with it. But you have to understand that every time there's been a major shift in the web, it has very quickly become about the routing making the paradigm. I mean, the web is built off the URL in the first place. You have a resource location. That's the whole thing. So server side routing has been with us since the beginning. When we moved to single page apps at that point, now, by definition of the change was that we were routing in the client. Some of the earliest single page apps didn't really reflect things in the URL and didn't really route, but we got hash state. Ryan Carniato: And then finally our apps felt like a website. And that was that first stage, that first generation of single page apps. Where you route completing the client. But as everyone knows, the hash doesn't make it to the server. That's something that the client gets to own. And that's why it worked really well for those first gen. But it took us getting to push state and history APIs so that we could actually use the URL as the server and acknowledge it. And that was key to the next generation, which is what we've been seeing now. Which we have server rendered apps that start on the server, and then continue on in the client. We needed to be able to communicate that information. And essentially the routing defined the paradigm. And that's going to be true of the next generation of solutions here. Ryan Carniato: If we've acknowledged that we need, let's say, a more multi-page app mentality here... which I don't know if that's clear to everyone why. But these optimizations are all based off knowing what renders on the server and what renders on the client. And even in cases where we can be very aggressive with our lazy loading, with framers like Qwik, we still don't want to ever just rerender everything in the browser. We don't want to load anything. So universally we are looking at server rendering again. But obviously we don't want to give up what we've had in the client. And I think, for me at least, this starts again. I mean, when you look at the optimization, it always starts with someone playing with the optimization. It was the same with single page apps. Ryan Carniato: But when this becomes the reality, it's going to be because there's a routing paradigm that actually supports that. And that's what perks my interest. I'm looking out at the wider ecosystem, thinking about what people are working on. That's what's been exciting to me. Because you can tell when that paradigm shift's happening is when people start working on routing again. And you've seen it already. Think about the way, say Remix, is doubling down on React router. And even to a degree with [inaudible 00:33:03], this is what I consider the pinnacle of our current methods of how we're doing stuff. But if you wanted to just kind of expand this a bit further out, you can look at... I've been talking about it a lot on my stream obviously. Ryan Carniato: I can never say his last name, but Sebastian Markbage, who moved from Meta to Next.js. He was tweeting some stuff yesterday when he saw the Remix announcement. They just mentioned that they're going to bring their loaders into their router. So this is giving the benefits of Remix to everyone, not even people using Remix in the react ecosystem. He was like, "Yeah, this is great." But well, I just keep on going, yes, and. And it's because he's obviously been working on the React core team. He's already a couple steps ahead in terms of where things are going. And he basically indicated that that's what he's working on. The last couple months he is looking at routing again from the React core team perspective perhaps, and looking at React server components. And I think that this is very indicative of a larger trend of us moving towards what that next paradigm is. Ryan Carniato: So I just kind of put that in perspective before Dylan goes on and tells you a little bit more about what we're thinking here, and maybe some of the different patterns that are happening here. Because you are starting to see this alignment. First in the optimization. We haven't talked about React server components very much on the stream. But yet, the thing to understand is, even though they do a lot of interesting stuff that we should probably mention it, especially in terms of the way that they let you have the islands and rerender what's outside of the islands. Which is not a pure MPA or multi-page app mentality. The way you define your islands are actually very similar to Astro or Marko 4 or 5. Ryan Carniato: They obey the same rules. So that's why, when we're talking about these solutions, for us, they all get bucketed under the same sort of thing. Because you do see the common patterns. They are viewing what is stateful and what is server only with the same sort of rules. Which might seem surprising giving how wide the different solutions are, that we can all actually come to very similar conclusions. And sure, that's the optimization side. But routing is going to be the key to how we actually get to what that next generation of web framework is. Dylan Piercey: Right. And I mean, with React server components obviously routing comes into that as well. You need the router on the page that's going to communicate with your server that gives you back the data from what was rendered from the server components, right? Like essentially the way React server components works is, you can set it up with your URL state. It'll hit the server again, rerender the server components and send VDOM to the browser that has what was rendered by the server and then diff that. The nice thing about that is, you have some stuff that renders on the server. You get what is almost like HTML, it's a VDOM that gets sent down. But then you can update things in place. So you don't have this issue of like, you're navigating to a new page and you've thrown everything away. That is one of the main limitations of MPAs in general. Is if you've got something like an audio player, video player that you want to persist across pages, well, you just can't do that with an MPA because you're throwing things away. Dylan Piercey: So I think React has solved that fairly well. But from our perspective, we're trying to look at like, "Okay. We've done all this optimization from the MPA side of things. How can we maintain that optimization and what formats make sense?" And in a lot of cases I think... Well, essentially it's more or less been proven that if you're going to a whole new page, the fastest way you can get that page to the user is sending the HTML and the CSS with server side rendering or cash. Basically it's turbolinks. So if you're going to a whole new document, the fastest thing would just be to send HTML. Which I mean, like I said, with React server components they're sending you a VDOM which is close to HTML, but you lose some of the benefits of HTML. Dylan Piercey: Like, you can't stream. Maybe you can with their implementation, not 100% sure. But how are you going to diff it? So there's those kinds of considerations. But in the back of my mind, one of the main issues with that, is that React isn't aware of what things actually persist across pages, or what is consistent. So if you have a bunch of stuff running around the server with React server component... say it's rendering a menu and then you've got your app shell over here, and that's rendering client side, or your app body that's rendering a client side. So when you hit the server again, it's going to say, "Hey, render this menu," or whatever. And maybe the only thing that can change in that menu as described in your JSX is whether or not one of the... which page you're on, right? It's going to highlight the page that's on. Dylan Piercey: But React's server components is going to send you the entirety of the HTML or VDOM for that section. And so one of the things that we're looking into is essentially, okay, we know which parts of the page are actually dynamic, which parts are derived from state, which things can actually change and how they can change. So what if we could actually have a format that's like, okay, you're visiting a page. You came from this page, what is consistent across these two pages? Oh, we see that this nav element is consistent. What is dynamic in this nav element? Okay, it's just that class. And then we can send just the class to the browser and do essentially a fine grained update from that JSON format that we skipped, sending so much stuff. Dylan Piercey: Now the other piece of it, like I said though is, essentially if you're going to a whole new section, like say that nav was not rendered previously, and now it's being rendered, it was under an if statement or something like that. Well now it would be ideal for the server to just send the HTML and then for your client side run time to be able to just pick up where it left off with this resumability feature that Ryan was talking about. So that's where we're seeing things going. There's a lot of questions still to be resolved and stuff like that. But in general, it's like, how do you navigate between pages that are consistent and preserving as much as possible, while also optimizing the new page transition to the same way that MPAs have been able to do in the past? Ryan Carniato: Yeah. And I mean, MPAs have traditionally been a full page reload, right? And as we transition to these new approaches where we're doing the routing on the server, but letting the client do the updating work, so we can persist page state. The most naïve approach like turbo, and turbolinks or whatever, is just to swap the whole page out. And on the Marko side, we're obviously optimizing on looking at how we can do this at the most granular performant level. But there's still a question of how much work and how granular you want to make this work. So I think a lot of the experimentation that's happening right now is actually... and I think this will apply probably across the board to a lot of solutions, is looking to things like nested routing. Remix has popularized this form of routing again. Ryan Carniato: Ember router back in 2012 was so ahead of its time. I fell in love with it back then. That's when I got into Ember. React Router 1 was basically a complete tribute to the Ember router. They're like, what if we took Ember Router and pointed it to React. Somewhere along the lines around React Router 4 I think, they actually tried to streamline it to more how React user would like the experience. And they ended up cutting a bunch of stuff, which ended up pushing towards different paradigms. But people really enjoyed it and React Router is probably the most liked one. But when React Router 6 came out, they brought back all the Ember features again. And that's it's really powerful. I mean, for some of us, we never left that model. But it's awesome to see the React ecosystem get back there. Ryan Carniato: And I think it's also a logical place for us to start our exploration on the server side. Because one of the coolest things about nested routing is, you've already compartmentalized your page in terms to data fetching. Like knowing based on this section, what data I need, and in terms of view rendering. Because you might be able to leave header or a sidebar on the page and only replace the nested part. And there's no reason why this can't apply to these server rendering techniques as a way of minimizing the impact of change. There's still a lot of complexity here. Because as you know, you load your homepage on Twitter or whatever, or your profile on Twitter. And you switch between your tweets, and your tweets and mentions. Even though only that content in the middle changes, you still have to update the selection state of which tab you're on and all that kind of stuff. Ryan Carniato: And in a client side router, you're just like, who cares? The client updates it. But if something was marked to be only rendered on the server, well, because you know, something like that's pretty trivial for navigation, now you're kind of in this interesting boat. Because it's like, how do you update server only stuff that's outside of those ranges? But I think this is why there's exploration going on. Because we innately know that things need to get more granular. And there's always this trade off when you try and make things more granular. At a certain level, like maybe route section, or island section or whatever, it's pretty easy for a developer to come in and go, "This is my thing in market." But once you try and get more fine grained than that, it's much harder to keep track of what's going on. Which basically influences the solutions and decisions you can make there. Ryan Carniato: Whether you rely on diffing, like a VDOM. Or whether you rely on a compiler like what Marko or Svelte does. And it's a challenging place to work out the details. But this is where the work is now. Have a mental picture of what the optimizations are, even have them working. But how do we reconcile this back into a final picture? But if you can step back and see that picture for a moment, what we're talking about here is, having these optimizations. Basically, as I mentioned before, shipping only the JavaScript we need, running only what we need as we need it. Getting rid of a lot of these overheads. And yet actually navigate in the client. Actually, while the routers and the server's rendering stuff, have those transitions. You switch the tab, have it fade in or cross fade or whatever you need to do. Just because the server renders it, and the JavaScript on the client can still augment those transitions basically. Ryan Carniato: So potentially, a best of all world solution. But it comes with some stuff. And I think, this is for me at least, one of the most challenging parts of this whole thing is, I've been looking at it from different scopes. And the difficulty is, once you get into compiler land, we're talking about a whole different conversation. We're talking about a framework is a language. We're talking about different DSLs and stuff. And people like what's familiar to them, and they'll see stuff and just be like, "Oh, hell no." And this is one of those challenges. Because there's different trade offs to different things. And one of the things is, with a compiler it's always easiest to locally optimize things within your scope. And trying to extend these optimizations out of that scope requires certain concessions to the language. Ryan Carniato: And I feel, in my opinion, where things are right now is, we're all seeing the possible solutions, but actually butting heads really hard against JavaScript the language. Which is kind of interesting. That's why compiler just keeps on being like... you're like, "Oh, how do you solve that compiler? How do you solve that compiler?" It's because essentially everything we're trying is getting us to this point where the language isn't doing enough for us. But from a wider ecosystem step aside, if you've learned JavaScript and you know how that works, you don't want to learn another language. So this is a challenging space to be in. Because how successful compilers have been so far have been based on how familiar they are. Svelte arguably is one of the most successful at being able to get people on compiler. Ryan Carniato: You write code, it looks like JavaScript. It kind of looks like HTML. What you get is not what your writing. But... like don't worry about that, you know? But it didn't feel alien to you. And I think a lot of these techniques that we're looking at right now, we haven't been able to bridge that gap yet. Because maybe the experience does feel a bit alien. Because you want dedicated pieces to make this work. And that's the hardest challenge here. And why like so much of this is really interesting at DX space. Because for me, it's not clear that even if we have, say the best 'solution,' whether it could be actually adopted. And this is true of everyone exploring this space. Because there's just so many other elements to what people feel makes good developer experience. Ryan Carniato: And this is something I've been playing with a lot myself, and I'm sorry, I'm going on my own tangent here. But on the Marko side, we've really gone. What if you had exactly the tools you need to make this happen, built to purpose. And Qwik is coming with the same kin of mentality. Where it's like, what if we just built everything from the ground up with what we know we need, create the syntax, create the language, create the pieces we need to make this a reality. How smooth can we make it. How can we take care of all this stuff? And I think it accomplishes that. But is it unfamiliar? Are people going to accept it? Whereas like, we haven't talked about Solid at all today. Because Solid really doesn't do what we're talking about. In the same way React doesn't really do today what we're talking about, and Svelte, and none of them do. Ryan Carniato: But I've been from a different perspective kind of bet, which is like, how far can we take the just JavaScript thing? Because some people misconstrue Solid's compiler, it's not really... it's not aware of other stuff. It's just primitives and it just... everything's local. But it's gets its global composability through a run time. So it's not compiler first. And I've been riding both carts, so to speak. Trying to figure out how... Is there a future where we don't have to go all compiler in the same way? And that's what I've been exploring with Solid. And on the Marko said I've been like, what if you just made the perfect solution with everything at your disposal? Ryan Carniato: And it's a very interesting comparison and juxtaposition for me at least, to understand what those different dynamics are. Because most solutions try and fall somewhere in the middle. And I don't know if the compromise is worth it. I actually think in some of these cases, you just can't solve it with the compromise. And we kind got to decide what's valuable. But as I said, the promise here of what the stuff on this, when we talking about these resumability and these islands, is that there is a future where you have a single tool that literally is the most optimal at any kind of site you're building. Ryan Carniato: We don't have that today. Today there's a dichotomy. There's like, here's a website, here's an app. What we're talking about here, and what React and other components, and Marko, and Qwik are actually moving towards is actually completely covering the whole range. And that's ambitious as hell. And it takes a different kind of outlook. I don't know if everyone's ready for that. But I mean, I'm super excited to be working on it. Kate: Okay. Awesome. Dylan, Ryan, thank you so much for coming on. This was a fun episode. We could have spent easy four hours probably here. But you can schedule a couple more, of course. And is there anything that you want to send our listeners to, or plugs, plug your pluggables? Ryan Carniato: Yeah, I think first of all, the communities on Discord are completely where to go. The conversations are happening there in real time. I mean, obviously there's stuff like Twitter, which I think you should follow at Ryan Carniato and Dylan Piercey, which where you can obviously see tweets, and at MarkoDev Team and at SolidJS. But I think Discord is the path path to the future in the communities. There's always conversations. That's where things are happening. And beyond that, I'm just going to do a little shameless plug. I've been doing streams every Friday where I talk about a lot of this stuff. I have people like Dylan on as guests, and Misko, and various people. And we look at the future of WebDev from a framework author's perspective. So yeah, definitely search me up on YouTube. I'll provide the link, yeah. Kate: Yeah. We'll include those links in the show notes. Dylan Piercey: So thanks again for having us on. Kate: Awesome. Well, thanks so much guys, and we'll see you around. Kate: Thanks for listening to PodRocket. You can find us at PodRocket pod on Twitter, and don't forget to subscribe, rate and review on Apple podcast. Thanks.