React 18 introduces new APIs for rendering applications asynchronously on the server, enabling a simpler model for architecting and shipping user interfaces. When deployed on edge networking platforms like Cloudflare Workers, we can get dramatic performance and user experience improvements in our applications. In this talk, Sunil will demo and walk through this new model of writing React applications, with some insight into the implications for data fetching, styling, and overall direction of the React ecosystem.
Living on the Edge
Transcription
I look forward to disappointing everybody here. Hi. It's been a while. It's been two years since I've been up on the stage. My name is Sunil Pai. I work at cloudflare on the workers team. I used to be on the react team. They got rid of me pretty quickly. And we have react stuff to talk about, but before I do that, I do want to start by saying that I've missed you all so much. This is so weird. I met a bunch of people at the speaker's dinner yesterday. It's nice swapping stories, doing the same awkward hugs. There's the bro hug, the 200 hug, the fist bump, the weird elbow thing, and I think it's time to retire that. But things have changed for me. As you can see, I get way better haircuts now. I dress a little nicer, and especially for the occasion, shout out to Tom Dale. Hope I'm doing you proud. I've been eating better, exercising better. The last two years, there's not been much else to do. But the thing I'm most proud of, and I'm sharing it with all my personal friends here, is two days ago I finished 500 days smoke-free. I quit smoking. Which is just so happy. I'm very proud of it. This is the thing that I've been telling everyone. I'm super happy about it. But it does leave me with one complication. This has been my GitHub avatar for the last, I want to say, like, ten years. Ever since I've had one. And it's cool. I used Photoshop back in the day when I had a pirated copy. But it doesn't really represent me anymore. But a friend of mine did suggest a minor modification, and I will be uploading it later today. I think it's pretty good. This was actually made by Siddharth Kshetrapal. Thanks to him. And he's not here today because his visa got screwed. But I look forward to his talk as well. But I think that's a good modification. And that's my story so far. Cool. Let's get to the talk. So three things you should know about the talk that I'm doing right now. It's kind of boring. We'll be talking about a couple of APIs, but if all goes well, you probably won't have to use it. Things will just happen. And that's nice. That's kind of a nice thing about react. All the improvements are slightly incremental. Nobody really has to do any massive rewrites. You can leave old code as it is. This talk is a beta talk. Much like the actual APIs and the fact that react 18 is on the horizon, but you know there's going to be about a year, two years of experimentation usually when these things come out. Much like that, this talk itself is also in beta. This is the first time that I've put it together, what we're talking about. And it also means that maybe over the next year, I'll be improving the talk. So if you spot any mistakes, sorry about that. But it'll get better. This talk itself is in beta. This talk is also about the future. I don't usually do api talks. I like talking about the work I've done. But this I think is exciting enough that... And it's part of the react release that no one's really noticing. Everyone's talking about the cool hotness, which is server components and concurrent and all that. But I feel like this actually is way more defining for all the things we're going to be doing in the future. Okay? So those are the three things. Let's jump straight into it. Standard interview question for all web developers. How does the internet work? And when they ask you that question, really the question is... Hey, let's say you type in react advanced.com into your browser. What happens? And there are a number of ways to talk about it. You can go into it in a lot of detail. You can talk about it at a broader level. I'm going to be talking about it as a conversation between a browser and the actual website. Okay? Let's dive into it. So this is an Internet Explorer. So the E stands for Internet. A classic. That's the only browser that I've known. And it's talking to a new search engine I've invented called yoogle.com. Quite convenient that they're both an E, I think. And you ask it a question. Like... Hey, what can you tell me about the Amazon rainforest? You actually type in Amazon rainforest in search. And search engine says... Okay. Hold up. I got you. I'll let you know. And it goes back to its services and says... Hey, team. All y'all. What do we have for Pi that we can tell him about the Amazon rainforest? So maybe there's a photos team that says... Okay. Here are all these photos I have about the Amazon rainforest. Take this. The search engine is like... Okay. Cool. That's fine. That works. Imagine that. A search engine giving you flight tickets. I think that would be a killer service. Nobody else is doing it, of course. And it says... Hey, maybe Pi would like to fly to the Amazon rainforest this weekend. Here are tickets. Of course, I think it starts in December. It's gonna be a little while away. But here are tickets for that. There's news about the Amazon rainforest. Because it's not in a great state right now. It's being burned to the ground and being razed. And there's news about it. If you want to read it and get more depressed about the state of the world. But of course there's a little video service as well. And it says... Hey, here are some videos. If you would like a seven-hour stream of lush greenery, we got that too. Awesome. So then the search engine comes back and says... Okay. I got stuff for you. Here it is. Let me present it to you. Oh, I forgot. There are gonna be eight ads before you get to any of the content. It says... Okay. Fine. Here are a bunch of ads. Possibly from another site that sounds like the Amazon rainforest. And here's a bunch of content. Not bad. So this is how it works. You start a conversation with a server. It gets a bunch of data. Presents it in html as a website. So if we had to implement this in react as a react component, what would it look like? Well, you make a component. Let's call it an app component. You all can see the code, right? It's fine. You can see the slides later. You make an app component, which has a header, a footer, and you write five components for your ads, images, videos, news, flights, which takes a bunch of data and renders it. You pass it into something. So even the data itself, you fetch the data before you render the component. Like, hey, give me all the ads for Amazon rainforest. Give me all the images, the videos. Get all of it. And then render to string. This is what happens on the server. Usually a meta framework like gatsby or next.js takes care of this for you. But you say render to string, get the data and render it into it. Sure. Okay. This is how it works. It's not great. There are some tradeoffs with this model that you might have noticed. So one is that you can't really co-locate the requests, you know, like, say, get data with the actual component that asks for it. Particularly on the server. You could probably do this on the client side, but on the server, because it's a one-shot thing, you can't put them together. You have to get all the data first and render it. Or you have to do other stuff. It blocks the whole page on the data. Can you imagine? You won't be able to see any of the photos until all the videos have also been fetched. Or if one of them is slower, the other ones are blocked. It needs to get all the data before it actually renders it done. Which is why you end up doing hacks, right? It's great. There's a whole ecosystem of libraries and frameworks out there that like your next.js or your gatsby and fetching libraries like apollo and Relay, a whole bunch of graphql stuff. But let's admit to ourselves, it is kind of hacky that you have to build something separate that's not inside react itself to do these things. In the beginning it was fine because it involved experimentation, but now you have to stitch up a whole thing and use a meta framework to do it. It's just a little eww. It's not perfect. You feel a little uncomfortable with this situation. You always have to make tradeoffs. Do you do all your compilation when you build the page? What if it's a site with 100,000 pages, do you have to do it dynamically? It's kind of weird. But this is the state in 2021. It's kind of fine. I mean, many multi-million dollar startups and companies have been made around this api and other things, of course. Of course it's the website that got you the money. I don't think we should be fine with this. We can do better. I mean, this is a community that is built on experimentation and innovation. So let's take a little bit of a... Let's keep that aside for a minute and talk about a feature that the Internet has. It's an idea called streaming. The idea is that you should be able to send data down as soon as it's ready, even before you have everything else. I don't want to get into too many technical details about it. If you're interested, you can Google chunk transfer encoding for HTTP 1.1 and there's something else for HTTP 2. There's a whole bunch of specs. But I'll try to explain it as simply as I can. So let's take the same website and turn it on the side. Imagine that it's coming from that side to that side. No, yeah, that side to that side, right? In your one shot method, you would send it all in one go. But in the streaming method, you would stretch it out like chewing gum and send out the bits as soon as they come. You would be able to send a header immediately, then the ads as soon as they're ready, and then the photos, flights, news, videos, and then finally the footer. So what would it look like as a user when you start loading the site? So you would start off with the header, you wait a bit, and then the ads pop in. Wait a little more, and the photos pop in, and the flights, and the news, and the videos, and then the footer. That's better. At the very least, you're not blocking just the header being loaded, waiting for stuff like content to load. Which is fine. And to be fair, I think Google actually does do streaming. But we can't really do this in react land so far, of course, because it's still a one shot. We can do better. Anyone who knows me knows that this is my mantra. The nice thing about being a UX engineer is that there's no upper boundary on how good you can make user experience, right? You can just keep making it better and better. Anyway, so that was streaming. So let's keep that idea to the side. This is a react conference, after all. A couple of years ago, there was an experimental feature that was launched at react conf 2019. Holy shit, that's two years ago. That's a while. Anyway. They announced a feature called suspense, right? You could mark components as react.lazy and it would load it asynchronously and you could use suspense to mark like a spinner. There's also data fetching. The problem is that that never really worked with rendering to string or server rendering and stuff. Some people use it for client side apps and it's nice. It's a good model. We'll just quickly dive into it and see what it looks like. So in this model, for the same page flow that we just discussed, you would have, let's say, an ads component that fetches some data inside it and then renders that data. Big thing to note is that there's a bit of a glitch in the matrix. You notice that there's no await statement. And the way react does this is kind of funky. If you're interested in diving into the details, it throws a promise. It doesn't matter to a developer as you're using it. You just write it like it's synchronous code and you can use it. By the way, I've been using GitHub copilot. I did this and right after this I wrote function images and it filled in all the code for me. If you're using GitHub copilot, it's kind of scary good. It's AI for your code. It fills in your code. Anyway, so you would also have an images component that just takes the search term, figures out what images are there for it and spits out the html that, well, the DOM tree that would work for it. Similarly for videos and for the ads and so on. And then what you would do is you would revisit your app component and you would wrap all of this with a suspense component and you would give it a fallback. Let's say a spinner. And the nice thing about the experience for this, when it's a client side app, is that you will have a spinner that waits for all the data to load and then finally renders it. So the experience would be, hey, you'd render a header and a footer and a big spinny spinner in the middle. I should choose a better one. It's not quite... It's fine for now. I can ship it, right? So it waits for it, it fetches all the data and as soon as that's done, it renders the content. That's not bad. But we can do even better. That's the mantra for today, right? Let's say that you can also mark each of those components with a suspense boundary. And let's say for the sake of discussion here, each of them have the same spinner. You wrap all of them up and then the loading experience for it is, hey, it starts off with five spinners. Maybe the flights loads first. Not bad. Then after that, maybe the ads load. Then maybe close to each other, the news and the videos load. And then right after that, the photos load. That's not bad, too. Like, at least as content... It doesn't wait for everything. As content comes in, it renders. But still not so great. Like, you want to load it at least in kind of order, even if the data resolves. We can do better. One of my favorite components, by the way, is a component called suspense list. Mark that out with the green boundaries. You can see the code later. But you can group together suspense components and you can say, hey, reveal these as in a forward order. You can also make it backwards, you can make it all together. It's a lot of fun. Feel free to try it out. Anyway, you can say, hey, make sure that the ads load first. At least the data for the others loads later. Just so we're clear, the data for all of them is happening at the same time, but just make sure that the first one is rendered. And then I group the other four inside another suspense list. Nested suspense list. That's cool. And say that I want those forwards as well. Okay. So what does the experience for that look like? Again, we start off with about five spinners. There might be data. So the ads load in. Some content might have actually loaded for the others, but we have marked that it needs to load in this order. The photos load. Then let's say two of the next ones loads really quickly. So your flights and news. And then the videos load. That's a much better user experience. But the problem, of course, here is that this is now a fully client-side rendered app, right? So we have this tradeoff. We have these two tradeoffs. One, we can either generate all the html on the server side, but you have this janky programming model and you have to make sure you have hacks or a whole bunch of optimizations that doesn't really gel well with the react model. Or you can do it completely client-side and have ostensibly a better user experience once all the javascript loads, but load performance is worse, it takes a long time for the javascript to load, and then the requests have to go from the browser. So you have to do one or the other, right? The mantra. We can do better. So this is the one api that I've been talking about. It takes render to string, which we've been using for the last five years and it's been fine. And it replaces it with render to readable stream. So we can now do streaming rendering with react. I just want to recap how good this is. So let's just recap. So we're going to look at the same thing that we looked at right before this. Traditional streaming looks like this. It stretches it out like chewing gum or a rubber band, I guess, and starts loading things one after the other. So the header would load, then the ads would load, photos, and all these blank spaces, which is fine, but it's loading, right? And videos and the footer. So this is what we could get if we had used traditional streaming, which we can't, just so we're clear, but if we could, and possibly how Google already does it. But with render to readable stream, you can start off with the spinners. Wait a little bit, the ads load, the photos, the flights, the news, the videos, and here's the kicker. That entire experience happens before any of your javascript loads. This entire experience is happening down the html. You can have a superior user experience without javascript on your page. So how does it actually do this? It's kind of cool. I have one slide to show you this, but really you should dive into it after this talk, all right? So what it does is it sends that shell ahead, and it knows that because that's the component model that we've done, but as soon as the page is over, it starts sneaking in little hidden divs with the content inside it. It's fancy as hell. Well, it's not fancy as hell. It's actually quite a hack. It works really well, even for like seo and stuff. And as soon as each of these bits load in, it's like one line of javascript. It's like one function call that just says, hey, take this div and replace the spinner with this content. There's no react on the page, no nothing. You can even remove it and you still get the same experience. So that's pretty dope, I think. And this is pretty fundamental to the rest of the react, the innovation that we'll probably see over the next year, like server components, the new hotness built on this tech. Any ideas that you have for new css and JS libraries, because it's been a while since we've had a new one. Might as well make 12 more over the next year. You might want to make sure that it works well with the streaming rendering model. You could data fetching now becomes way more interesting, right? Because now instead of the hydration step being one blob of data that you just inject in there, you can do it piece by piece if you want. Lots of fun stuff. Anyway, so just to recap. So the new server rendering features that we have, once you replace render to string with just one line which is render to readable stream, suspense just works. This is a huge deal. It's not worked for the last two years, which is why a lot of people haven't even used it in react apps, but now it just works. react.lazy, all that. You get to do loading patterns. Again, without your javascript bundle on the page, it just works. You can use suspense list and suspense boundaries. Very cool. This is my favourite thing. The spinners work without the javascript bundle on the page and in an order that you can decide. Which is honestly I feel like all frameworks should steal this idea, and of course they steal from react all the time and say, oh, we're already better. Then again, they do ship before react does, which is like... Eww, sometimes. Do you see why they didn't want me on the team any more? But then there's a bonus feature, and I actually didn't include it in here because I didn't think I would have time. So the page can actually start racing your javascript bundle with the server streaming. In the beginning, when you start up, it starts streaming down all the server, all this html, right? But it can also start loading the javascript. Usually the first time you're visiting the page, the javascript bundle might take a little longer to load. But the second time you visit the page, it's cached. Which means the javascript bundle loads immediately. At this point, react tells the page this is not a server-rendered page any more, it's now a client-side app. And it immediately takes over so it can load even faster than the server-rendered page. Wild feature. I just love it. So it can actually race client and server side. Very cool. So these are all cool features. But there are tradeoffs, right? That's the other thing I say. None of this stuff is actually free. What you really need to do now is run your own server. Some of you might have been using a create react app or something that was client-side only. But if you want these performance benefits and a better programming model, just happier users really, you now need to invest into a server runtime. So you have two major choices to do this. One is node.js. I love Node. It took me from a toy javascript UX developer and made me a full stack developer. Love it. Didn't have to change much. Just plain javascript. Shout out to browserify and stuff. It was a pretty great day about ten years ago. But what you do is you either have to rent hardware, a VPS or one of those things with a host like Heroku, DigitalOcean. I don't know. I haven't done it in years. I think there are others on the market. Relax, it's just a dry cough. I'm fine. Yeah, so you pick one of these machines and you then have to set it up, you have to set up process monitors. The moment it dies, you need to do a restart and monitoring. It's fine, I guess. I'm excited about stuff like fly.io. It tries to give you heavy metal on the edge. Picks a bunch of cities and you can pick it and deploy your code onto it. Shout out to Kent. He deployed his site onto it and it's really fast, really great service. They're doing some really cool stuff. They seem to have hired a bunch of interesting people. But it still isn't trivial trivial. You still kind of have to deal with your server. Or you do what's called serverless computing. Which is your aws lambda or your Wurzel. Which is fine, but the problem is they don't support streaming. The api does, but it buffers it and only once it's done does it send the content down the pipe. Which kind of ruins the effect that you want. You want it to load early. So that's choice one. What you can do today. I bet some of you have your stuff up on Node. It's not a bad choice. It's a Node isn't really built for the lambda use case. Which is the suicide use case. It takes something like 200ms. Last I checked. I don't know. I could be wrong about these numbers. It takes 100 to 200 milliseconds. You can look for cold start time and you'll see people talking about it, I guess. But choice two is this new breed of serverless computing that's happening across the world. My employer has something called workers, something called edge at compute. If anyone has used it, let me know. It's very hard to use it right now, but I hear great things about it. The new kid on the block is of course deno. They have something called deno deploy. shopify has something very interesting, which is they have their own runtime and framework for deploying shopify-specific components. And I think someone's speaking about it later in the conference. I'm super looking forward to it. Very exciting work. gatsby, I think, now runs. gatsby used to be a static site generator, but they're not so much, but they're not openly admitting it. And they run something called gatsby cloud. It's cool, by the way. It's called DSG. Very cool tech. I think Siddharth is here. He'll be talking about it later. And there are going to be more. There will be a lot more people who will be... I expect more people to try this out. And there are some usual patterns. I would like to talk about cloudflare workers. I mean, I picked them. They pay me for this. It's kind of nice. So cloudflare workers, right? It's a standard-based runtime. You can do stuff like fetch, regular request response, a whole bunch of web standard APIs. No DOM APIs, but you don't need that on the server side so much. You have react there, of course. Which is nice. The code is super simple. You don't have to spin up and say a port. No, you just export a function called fetch that responds to a request and returns a response. Super nice. It's across 250 cities across the world. 250 cities also, like, it's a small number and a big number. It's the biggest network I think right now. And they have deals with something like 10,000 partners or some shit like that. The employees aren't told where in the cities the actual data center is, by the way. So we like joking amongst ourselves that it's either underneath the tube or it's in the air traffic tower in Heathrow, because that's where you get the best reception. It's either that or the BT tower. We're not sure. But like massive network across the world. And the numbers are kind of wild. Because they have such a great network, they're within 20 milliseconds of 80% of the connected world. And within 50 milliseconds of 95% of the Internet connected world. I'll show you how fast that is. I want you all to try something with me. I want you to blink as fast as you can. Try to count how fast you can do it per second. Ready? I'm like the blinking meme dude. So I can do about three to five times a second. But cloudflare can do about 10 to 50 requests in the same amount of time. Which means if you actually write your site well, you can load your whole website in a second, maybe two. It's really fast. It's scary how fast it is. And what I really like about stuff like workers and the other runtimes is they all have zero startup time. There's none of this cold start time or anything. It just starts up. You can start it. react starts up. You have all the data. Throw it down the thing. But it's not just good enough to have a runtime that runs your javascript. You also need some kind of persistence. Because we have this javascript here, but your database is halfway across the world. Still not great. So workers also provides a little key value store, which is just, hey, for this key, store this data. And you can fetch it where you want. Which is also replicated across the entire network, which means the runtime and the data is, well, on the top of BDTAR. And we also have the sci-fi thing called durable objects, which is the coolest thing I've heard of. They're literally javascript objects that can move from data center to data center, depending on who's asking for it. It's wild. What that means is, let's say I... And you can use it for WebSockets and synchronization and stuff. Which means I'm talking to a friend in, let's say, San Francisco. I don't know anything about American geography, but let's say New York is between London and San Francisco. Maybe. Let's say. Somewhere midway. I don't know. So the durable object that we use to establish a WebSocket connection between each other could potentially migrate to New York so that we get the best data to talk amongst each other. And then let's say a third person joins us from China. In which case, maybe the object figures are the centroid of these three locations. It's all very sci-fi. This is... We're trying to figure out what the database story around it here is, but it's a very novel invention, and we're dying to see what people build with it. And there's so much more. And when I say so much more, I mean cloudflare has a deep portfolio of services, and you should totally go check it out. There are also so many cool things we're building that I'm not allowed to tell you yet. What you do is you buy me a beer right after the conference and then I'll start talking a little bit. But I can't do it on screen. Ha ha, hey, boss, manager. Anyway. So you can go explore more at workers.cloudflare.com. It's a startup, there's a CLI you use, and you can start writing javascript and it works. It'll be getting better soon. But the vision really for workers, and I assume all these other runtimes, right? I want to stop calling it serverless. What I really like to imagine it as is it's one server that envelops the world like a buckyball with your database all surrounded. Anyone taking a photo of this? I look like a maniac, I'm sure. So you can envelop the entire world in this mesh. Right now it's 250 cities, it could be thousands in the future. We might give you some hardware that you can just chuck behind your washing machine and then you could FTP into it and set your website up just like the 90s. It would be great. So edge networks like this are such a good fit for the react streaming model. It's instantaneous. We can give experiences that are way better than anyone's had in the past 30 years. Wow, the web is getting old. So while there is going to be an incremental story where we improve all these things, what I really think is going to happen is that this is a big reset moment for react. Of course all the popular libraries will still work with the existing model. The team itself is collaborating with css and JS library authors, data fetching library authors, and it will work well. But I think there's potential for us to do more. For example, Node really doesn't run on these networks, which means next.js doesn't really run on it. I don't know, next.js might make, the folks might make some changes there. But it sure would be nice if we started exploring saying, hey, if we had to build something from scratch, which used streaming as a rendering model, server components for data fetching, way more lightweight libraries, and the ability to talk to APIs like durable objects and KB stores, what could we do? I want to leave you on that note. I want you to start thinking about what this means for react and the ecosystem. A lot of the complaints about react have been bigger bundles and overengineering and javascript fatigue, but maybe this is a moment for us to start removing the fatigue, to start simplifying the stack, to start removing the parts that we have needed just to be able to have a competent stack. And maybe we could have a different story. I don't know. I'm going to try. I expect everyone else to because I don't usually ship my libraries anymore. But there are folks out there who will look at me and be like, I find challenge accepted. I would like to see that. There are some links. Well, you can just literally Google react 18 working group and you can find a bunch of details about what I was talking about today, how to upgrade to the new api, guides for library authors for how to upgrade their authors, how you could possibly build a new javascript runtime if the next big serverless entrepreneur is in the crowd here somewhere or watching this in the future. There's a whole list of like... Sebastian from the team wrote down a list of things you can do to make it better. And yeah, I look forward to it. I'm super excited about this very simple api that I don't expect many people to use by hand but I expect will be redefining the experience for react in the future. My name is Sunil. You can find me 3.1 on Twitter, which is the worst thing to spell out to somebody on the phone when you want to tell them what your email address is. Yes, it's 3.1, all words, no numbers, no dots. You can reach out to me there. I'm happy to talk to you after this. And I'm looking forward to talking to all of you at the conference and grabbing a beer after this. Thank you so much. Thank you. Thank you so much, Sunil. Would you step into the Q&A lair? You don't even need to bring your own water here. We have water at the Q&A lair. It's quite a special place. Hey. Hi, Ani. How are you? I'm good. How are you, Sunil? Not bad. Thanks for a wonderful talk, as always. This is, I think, the second or third of your keynotes I see. And every time I leave, you know, like kind of surprised by how interesting you can make api talks or these kind of like, you know, technical things. Your sarcasm is duly noted. No, no. I think it's sincere. We have a couple of questions from Slido. So let's jump right into it. We only have a little bit shorter, five minute Q&A for this first session. So there's a couple of questions. I'm going to start with a spicy one, just because, you know, I think that will probably get some interesting conversation going. Needing a server feels like the new normal in react. Is this an admission of defeat for static sites? Not at all. The web tent is very, very big. And static sites have actually proven to have some kind of staying power. Particularly because it's not just because of react. It's because it's been that way for the last 25 years. The first websites were technically just static websites. Until PHP folks came and made it interesting. No, I don't think so. I think there will always be use cases for static sites. What I really think is going to happen is that a site is not going to be a particular type anymore. There are going to be pages that are great, which are pre-rendered and static. There are going to be pages in it that are highly dynamic. And there will be pages in the middle of it. I think Rich Harris gave a great talk about this recently where he coined the term. We as a community love coining terms called transitional apps. I think that's really what's happening here. It's an evolution of the entire ecosystem, not just the react ecosystem, of understanding that there's no one size fits all. But there has been for a long time this kind of like... Maybe a false dichotomy between server rendered sites and maybe client SPAs and this sort of static CDN delivered websites. And people have emotional connections with those ideas. They take camps, they take sides. What would you say to those people? Don't take it so personally, man. It's fine. Things change. That's the nice thing about this industry. Really, like I said, as a developer, you are now more empowered to create better experiences for your users without compromising on performance characteristics. I think that's a good thing. You get to pick parts of your site. Not only do you get to pick, but you get to change your mind. At some point you decide, oh, maybe this wasn't meant to be a static site. You can turn on the dynamic nature of it. It's pretty good. Nice. Thank you. Let's go for a little bit more technical question. I think this has big words and I know some of them. With server streaming, how do you set intrinsic size of page sections to avoid janky reflows as different parts of the page with variable lengths load in? So you answered the question. Server streaming, how do you set intrinsic size of page sections? So basically the idea is that if you have elements that have a size that you don't know how big it is until it streams in. So I think this is more of a product design question. But there are a couple of things that you can do. People say there are spinners. You can use skeletons. Is that right? Like little sections that look like what it's about to be rendered and hopefully when it does render, it fits the exact size. I happen to think that we are going to see a resurgence in animation so that when content actually does come in, it smoothly transitions to a newer size. Or you use like suspense boundaries. And that's the big deal here. You can actually mark off sections that you need to stay stable until all the data loads and then renders in. So yeah, there's like options. There are things you can do. Nice. Thank you. We're going to keep this first Q&A a bit short just to make sure that we're on time. There are a couple of questions there. One is how it is to work at cloudflare. It's dope. It's so good. Everyone is so nice. I'm not even like joking. I reached out to them. I was like, please, like, let me work with you people. You all are super interesting. During lockdown, Sunil and I discovered that we live quite close to each other. We've been meeting for walks. And he has relentlessly not stopped trying to hire me. I don't shut the hell up about these things. So if somebody is looking for a job at cloudflare, I think this is a man to talk to. Or a job in general, I suppose. Exactly. He'll sell it to you, I'm pretty sure. All right. Let's give it up for Sunil. Thank you, Sunil. Thank you.