HTTP/3 Performance for JS Developers with Robin Marx === [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. Tried for free@logrocket.com today. My name is Paul, and joined with us is Robin Marks. He is coming to talk about his latest JS Nation talk, and he's certainly an expert on things attp web and transport, so he's a web and network protocols expert over at Akamai. We're gonna be digging a bit into ATTP three. What is it? Why is it important? And especially from the purview of somebody who might develop full stack applications? Doesn't matter to me. Welcome to the podcast. Hey. Hi Paul. Thanks for having me. Happy to be back. We already talked about HCP three, I think a year ago. Yeah, there is some new interesting developments since, especially for Java, good developers. So that's what we'll talk about today. Yeah. So we had you back on in [00:01:00] 20 July, 2022, and we got into, yeah. What is HTTP three at a basic level. How is it different than attp two? If you want to go check that podcast, please do. But for folks who haven't listened to it, Robin is ATTP three something new on the block. Cause a lot of times when we bring people on, we're like, Hey, there's this new feature, there's this new thing coming out. It's something that maybe hasn't been released or it hasn't really been seen yet, but that's maybe not necessarily the case with htp. No, by now, H three is really quite mature. I would say it's fully supported by all the main browsers. And there are a lot of big developers big deployments. I would say that already enable it. So especially if you're using a C D N content delivery network like Akamai or CloudFlare, you'll already be able to use http three. It's still a bit difficult to set up yourself. If you have your own Apache and Gen X, no JS server, then it's more difficult. But outside of that, it's really quite mature and ready to use today.[00:02:00] So what is the general landscape for folks that are wondering? Like I'm used to seeing http. I'm seeing Protocol two, version two in my debug and all that, I haven't noticed three. Where is it deployed? Where is it common? Yep. So it's mostly common in very big deployments. If you look at Facebook Meta all on H three Google, YouTube, all on H three Amazon. Those kinds of properties. All of those are mostly H three. You can also see this in, for example the browser dev tools. If you enable the protocol column, you should see H three showing up quite a bit for those those bigger websites. Yeah. Gotcha. And I'd love to, just really quickly before we step into some of the new content that you're putting out from your talk about, optimizing for JavaScript developers. If we could dig a little bit into what makes H T P special, because we're gonna be talking a little bit about round trips. And how we're getting data. So it's my [00:03:00] understanding that there's something different than how it uses TLS and tcp. That's the big difference between hhp three and two. Could you uh, shed some light on that for us? Yeah, that's exactly right. So if you just look at the http part, Then three and two are very similar. They have very similar features. It's really underneath that, that things have very much changed. So if you've ever heard about the protocol stack and the transport layer and that kind of stuff, that's where things have changed. So Htcp two runs on something called c p, the Transport Control Protocol. And it uses t l s, the transport layer security protocol for encrypting. Your pertinent user data. And that's a very big difference with Hctp three. This no longer uses tcp. It uses something very new called Quick. Quick is a new transport protocol and quick also still uses TTLs. But in a different way than tcp. With tcp [00:04:00] TLS is a very separate protocol. It's used separately from TCP with quick. It's deeply integrated into the quick protocol, which gives us a lot of efficiency improvements because they can work together much tighter than TCP and TLS can. And so the main difference between version two and version three is really at that lower layer, the change from TCP to quick. And that brings us most of the differences , and most of the benefits. So that's the main difference between version two and version three is that it changes TCP for quick and quick is where most of the differences come from and also most of the benefits of HTTP three. And for folks listening, if you're hearing quick, we've had Mishko on here, who's the author of the Quick Web Framework. This is different. It's spelled Q U I C if you want to go Google it it might make you raise an eyebrow when you first see that spelling, but that's what makes it special. It'll make it easy to Google so you can go [00:05:00] find documentation on it and find out more. So Robin, , when we have this quick box sort of replacing the T C P box and using TLS \ , in this new way, what are some of the top level or top of mind benefits that people might observe or try to reach for from having that? We're gonna be looking at round trips, right? So I'm specifically wondering how does that save us? So that's one of the key benefits, right? As I said, TCP and TLS are separate. And to get a connection set up, they both need to do their own, what is called the handshake. So they need to exchange some data between the client and the server to set up the necessary parameters. And this takes some time on the network. This takes a network round trip to exchange this data. And so TCP first does this. It's one round trip and then TLS needs to do its own handshake. That's another round trip on the network. And only after that can you get [00:06:00] HTTP two sending and receiving data. And so that's the nice thing with quick is that it can do boat, the transport level handshake. So the quick level handshake and the TLS session handshake, the encryption parameters exchanged, all of that can happen in the same round trip. So instead of having two separate ones, you can only have one at the very start, and especially if you're on a slow network or or you're connecting to a server far away. That can make several hundreds of milliseconds difference in, in how long it takes for the connection to set up. And so , also, for example, , to how long it takes for your page to start loading. . So with tls, grandfathered into the quick box. It's not its own layer we're talking about, it's inside. The quick, does this make the stack, the networking stack that you might be dealing with as a developer? More like a black box versus, I can use this TLS version, that TLS version I want to use a do not want to use. Do you feel like it's a black box? And do you think[00:07:00] if so, this is a good thing or a bad thing , for the average web developer when they're using this stack? Conceptually it makes it more of a black box, I would say yes. So you have slightly less freedom conceptually than you used to have because, you're really stuck with this. You can't use quick without. Tls and you also can't use quick with TLS 1.2, for example. You can only use it with a newer version 1.3. So in that way, yes, in another way you can really ask yourself the question. Does that really matter? Especially for front-end developers. You didn't configure your stack yourself anyway, probably. So in practice, I don't really think it matters at all. And in a way it's good that we use the protocols as a as a black box and that we don't try to force too much configuration on top of them because that allows both the server and the browser to make the necessary optimizations. And we don't really need to think about those. Those just happen in the background. We just get the use and benefit from [00:08:00] them. And last but not least, so we talked about reducing handshake time, both like roping TLS into the T, the quick layer, which might have been separate from tcp. Traditionally, what is this Robin or is this different than what you would tokenize as the zero R T feature? Huh. So zero RTT is like an extension of that where it becomes even more interesting. So the default way that H three and Quick work is you have one round trip for the handshakes, so quick and TLS handshakes, and then in the second round trip you will send your H three request and get a response. So it's two round trips total to get some H three data back. Zero R T makes this even better. It allows you to send your H three request alongside the quick and TLS handshake in the very first. Round trip already. [00:09:00] So instead of having to wait two round trips, you actually get some response data back in the very first round trip already. So zero R t d, it's a bit of a weird name I always think, because you still need one round trip to get something, but it's zero overhead. All the overhead of the lower layer protocols is gone. You get immediate H three data transfer going on. So zero RT is like the best we can do. And. Also something that quick and h re enable. So we've had a lot of ground covered here. We've talked about some basics of the HTTP three protocols, what gives it the edge, why it's interesting, the zero R T T, and like we mentioned at the beginning of the episode, if you wanna learn more with Robin in particular, go check out the episode we had last year in 2022 with Robin Marks on htp. We're gonna hop into Robin talking a little bit about your JS Nation talk and why. How could this matter for web developers? Before we do that though, I just wanna [00:10:00] remind our listeners tuning in that this podcast is brought to you by Log Rocket, and if you're developing either in the service side or on the client side, you're trying to speed up your application Log Rocket is there to help you along the way, can help you solve errors faster with issue tracking surfacing patterns that you might not find naturally with ai. Helping you develop your application faster and spending more time, actually building and less time debugging. So if you wanna try it out, go to log rocket.com today and you can try it for free. So let's turn our attentions back to your JS Nation talk that you gave Robin. Why would somebody who's developing a regular web application right now in 2023 start to really maybe feel enticed to learn about what we're talking about here? And use it to start to speed up their web application. Yeah, good question. So as we just talked about, most of this is a black box, right? And that's good. You don't need to care about it. The only thing you really need to do is just enable H three [00:11:00] on your hosting provider or your cdn if you're using it and you get zero R t, but also a lot of other performance benefits, like for free. You just get them outta the box. Usually it's a good thing. The thing is, as front-end developers, sometimes you do want like a little bit more control. Like most of the protocol features are fine and default, but sometimes to get optimal webpage loading performance, to optimize things like the Google Core web vitals, you need a little bit of extra control, and that's where it sometimes goes wrong because you get this control through like very high level browser. Features, html markup that you can add. Things like preloads, maybe things like async or defer JavaScript tags attributes, I should say. Those are very high level features, but what you might not realize is that they actually impact how the protocol works underneath. And so most people use these [00:12:00] features in a bad way, inefficiently or sometimes even incorrectly. And so they don't get optimal performance from the underlying protocols. Could you maybe shed some light on what one of these protocols might be and how it could be specifically used in an incorrect way that maybe would catch people off guard. Yeah. One of the main Problems I sometimes see is that developers pre-load. So they use the pre-load directive for an async or a Dever JavaScript. And that. It depends on what they're trying to do, but usually that's not the best idea ever. And they don't always understand exactly how preload works and how that impacts async and defer and how that actually works together with something like HTTP three. So to understand that you do need a lot of internal knowledge. I'll try to condense it as much as possible. Of course. So the thing is, Both HTTP two and HTP three, they use only a single underlying [00:13:00] connection. This means that if you need to load a lot of different files on the webpage you need to somehow decide in which order to load these files. Am I gonna send the HTML first or realize send the CSS first, or maybe the JavaScript first. And which of these is better for your eventual web performance? And the way that's decided, who decides in which order to send these files? That's actually the browser. The browser will decide, and that's where like stuff like preload and acing defer come in. The browser decides what the order of the loading of the resources should be. And for example, let's say that you if you have an async or defer attributes on your JavaScript. What Google Chrome will do is say, okay, async and differ is to me a clear message from the developer that these JavaScript files are less important than, let's say, JavaScript files in the head, [00:14:00] or even less important than some images on the page. And so Google Chrome is gonna tell the server, these are asing D for JavaScript files, you should load them relatively late. In the webpage load, these can be delayed, right? Other stuff is more important. That's how that interacts with the protocol, because the protocol gives you the features that's called prioritization. Hctp three offers this prioritization and the browser uses that to tell the server, this is the order in which I want this to be sent. And ASIC can defer that should probably come relatively late in the page load. That's what the browser does by default. What happens then if you preload one of those async or defer JavaScripts, suddenly the browser is going to say it's not necessarily gonna say this is more important. It's just gonna say, I don't really know if this JavaScript resource is being async or defer [00:15:00] tagged. Cuz you probably know if you do preload, you add that to the head of the HTML file. The actual file is, for example, only loaded at the bottom's. What you often see with server, with server site rendered single page apps, for example, nowadays they had a pre-load on top, and then the actual files are loaded all the way on the bottom. So on the top when the pre-load happens, the browser doesn't even know if this is gonna be an Async or D for JavaScript, and let's go to request the JavaScript at a very high. Priority, a high importance should be sent very early on in the page load because it didn't even know if it's async or defer at that time. And so what you get because of that is that your JavaScript file, which is probably less important than let's say your largest content, full paint image, or or let's say your funds for example, they actually get loaded very early on in the page load because you decided to To preload them. And that is an interaction [00:16:00] that I've found that a lot of developers don't really understand and why that matters in practice. It's almost like an escape hatch that you're digging for yourself. Would that be a fair. Comparison to paint here, there's all these guarantees or benefits that the protocol can give, but when you use the higher level a p i, you're taking control and you really need to understand what that prioriti, how the prioritization's being affected. Yes, exactly. That's the whole point, right? So the high level features, they don't, they give you direct control over the protocols, but they do influence how the protocols behave underneath. And if you don't understand how that works, you will end up making making a lot of mistakes. Gotcha. So what do you say to the folks listening who go, I have a CRUD application. And I just use like fetch. Okay. Or some like [00:17:00] loaders or API routes to, to do some cross site, maybe serverless calls. How does the Fetch API change or affect the way that you might develop if you're building on H three? Yeah, and that's a very fun one. Because there you see there it matters a lot as well. So the fetch API calls all of the browsers, basically anything you fetch, they see as the same type of resource. And so all of them are also the same priority, so the same. Moment in time where it needs to be loaded in the webpage load. The thing is there, very important, the browsers don't agree on how important fetch calls actually are. So for example, Google Chrome. In Google Chrome fetch calls. So if you do a fetch call to anything is equally important to a parcel blocking JavaScript file. For example let's say you're loading a JavaScript file on the head, and [00:18:00] before that you do a fetch call. Then the result of the fetch call is actually going to come in, it's gonna be put on the wire. It's going to arrive before you get the JavaScript content of the, of your actual JavaScript file. Might seem okay, might seem reasonable. The thing is, this is only in Chrome. In Safari and Firefox, it's reversed. So in Safari and Firefox, the fetch call will complete after the JavaScript in the head is is loaded. So basically you get a different order of loading the resources depending on the browser that you are that you are using. Gotcha. So , do you have any preconceptions about why this might turned out the way between the browsers? Cause there's always been differences in the browsers, but this feels like a very fundamental, almost like VM level difference between them. Yep. Believe me, I've asking, I've been asking myself that question for a [00:19:00] very long time. It was actually my main topic in my PhD research. What I found there mostly is that The developer of the system or the developer of the browser just chose whatever seemed okay to them at the time and didn't really take the time or the effort to actually test in practice what this would do to page loading performance of common websites. And nowadays it's been a bit better. This has evolved a bit for the better, especially in Chrome. So Chrome is doing a lot of tests. Nowadays, whenever they change something, they try to look at real user data and everything, which is not really the case for Safari and Firefox. They just have a developer thinking, okay, according to me, this is the optimal approach and I just choose that. Whether or not that's actually true doesn't really seem to matter to them in practice. Sadly, Gotcha. So if we're talking about fetch and maybe doing a, get a post request you mentioned, using some higher level APIs. All these things can change [00:20:00] the prioritization in the way that you're interfacing with H three in your web application. What about resource discovery? The way that the browser might preemptively? Cuz we had, what was it? Please correct me if I'm wrong here, but was it like server push or something? It was like, Some way the server could predict what the client would need and would like preemptively push it. Yeah, so that's the other side of the coin, I would say. So prioritization is one thing. So for the resources that I know about, this is the key point. The resources that the browser knows about, in which order should they be sent? Then the question becomes, how do you get to know about these resources? How do you discover that a resource is needed? Again, sounds silly, but of course a simple example there is, let's say you have an background image defined in the CSS file. The browser will only discover that background image is needed after it downloads the c s s file. [00:21:00] Seizes the URL and the CSS file. And only then can it start to request that's one of the reasons that you have something like preload, right? To tell the browser , I know this will be needed in the future, even though it's not visible yet. I know this will be coming up, so maybe you can already start loading that. So this whole concept of the browser needing to have downloaded. A resource to discover its sub resources. So the resources, it's chill. Child resources, I should say, is a very key part of how websites of course work. And this is also true for the H t ml. You can basically do nothing at all until you get your H T M html or at least the top part, like the head of the html. That's where most of the top files are are there, and that's the key point there. The HT m l is often delayed because if you, for example, do server side rendering and you don't have the HTML in cache somewhere, it will [00:22:00] take a while for, let's say you're using no hjs, it will take a while to do a call to the database or to some microservices that you have running to actually get the data to then render the page. Through a template, which also takes a little bit of time, and then you can start returning the html. So basically that, that's what we call the server think time, server waiting time. What you basically get as a period on the network that you could be sending stuff, you could be sending packets, but you can't. Because you're waiting for the HTML to be generated, and during that time, the browser is also stuck. It can't do anything because it needs the first part of the HTML to start discovering and requesting the other resources. So that's the problem. And then the solution, as you said, The solution we thought was gonna be the solution. Spoiler or alert. It was not what we thought was gonna be the solution with HTP two was indeed server push. Where the idea being that while I'm waiting [00:23:00] for the HTML to be generated, I can already start sending data for my JavaScript for my CSS that I know the browser will need. The browser itself doesn't know it yet because it waiting for the html, but the server knows because I've configured it. The server knows you will need this css. You will need this JavaScript. I'm already gonna start sending it to you. I'm gonna start pushing. That's where the name comes from. I'm gonna start pushing the data for these files to the browser so that by the time the HTML gets generated, you already have the CSS in JavaScript as well, and everything is as fast as possible. But that didn't go exactly as planned, right? Yes, server push turned out to be very difficult to use in practice. I really don't want to go into the details because this is very technical stuff. What it again comes down to is that a lot of the browsers had different opinions on how this should be done. There were also quite a few bugs in their implementations. And the way that push itself [00:24:00] works often led to the server sending useless data. Data that the browser, for example, already had in the cache that does didn't need to be sent, was often still stent with push instead of actual useful data. Instead. So the end result of all of this the only thing you really need to remember about push is that it's now no longer used, it was removed from Chrome, for example, completely. It's not a feature that is still actively used today. So if we're not using push to and I'll call this the dead zone, right at the beginning when the browser needs to figure out what resources it needs to, so to cure this dead zone, we're not using push. So what is h three's answer to that. Yeah. So that's the thing, right? The concept of push was good. We do want to fill that dead zone. Like you say, that's still a good idea. It was just a push mechanism that was wrong. And so we now have something new, a new mechanism that is called 1 0 3 early hints. And the nice thing about this is [00:25:00] you say it's an HTTP three feature. It's actually not. It's something you can use with boat HTTP two. And HTTP three at the same time, because it's like a higher level http feature, not tied to the protocol version. But so this early hints, it conceptually is very similar to push. The setup is the same. The main difference is with push, you actually started pushing actual data. So you would say I read the first 20 kilobytes of the CSS file, and I'm actually gonna send the 20 kilobytes of the CSS file. That was push. What this early hint stuff does is slightly different. It's not gonna start sending the actual data. It's first going to send links to the resources. So instead of saying to the browser, Hey, here's 20 kilobytes of the css, it's gonna say, Hey, here is a link to the CSS that I think you will need. And that seems like a very [00:26:00] stupid distinction, but that's actually. What solves the push problems because now, for example, the browser can see, okay, this is a link to the css, but I actually already have that CSS in cash. I don't need to request this because I already have this, Let the browser decide let the browser decide. But look, hey, the server is telling me I will also need a JavaScript file that I don't have in cash yet, and then the browser can request. That file. So instead of the server pushing the JavaScript data, it's again reversed the browser requests the JavaScript instead, and then it can again use things like prioritization correctly, which it couldn't for for servers server push. So it's just a it's a, it's, it might seem like an insignificant detail. It's relatively technical. But, so just switching that from actually pushing data to first sending a few links and letting the browser request them actually solves all the [00:27:00] problems we had with push while getting most of the benefits out of them, and then some on top. For example, one thing you couldn't do with push is push assets from subdomains or from third party domains. Let's say you had your fonts or your images on a separate subdomain, you couldn't push those with one or three early hints. You can, you just send links to the subdomains and the browser will just open a new connection to the subdomains and and do that. So overall, much p much more powerful, much more flexible, but also much more robust than push. And so that really helps if you are If you have slowly generated server site rendered, for example, html, you have to wait for a long time. You can start letting the browser know, Hey, you al also need this while we're waiting for the html. You can already start downloading the css, the JavaScript, maybe even your largest convert tool, paint image before the H C M L even comes in. We're testing this right [00:28:00] now, and it gives you very impressive speedups of the, like we, we've seen about half a second Oh up on largest ful paint just from this. Yeah. It's That is exciting as heck. Like it's almost like you said, threw up your hands. You're like, I can't deal with all these browser confusions. You guys take care of it. I'll just tell you what to do. Robin, we're unfortunately like running up on time here. But there's a big feature that we have to. Zero in on before we end the podcast today, which is web transport, because this is, this feels like a biggie especially as in the developer community more and more like looking back to back on our shoulders and we're looking at the fundamentals, like what is a form, what is, what are web components and stuff? So let's talk about web transport cause we did mention fetch earlier. Maybe through that lens we could step into this combo really quick. What is web transport and how does it. Relate slash be a contender to fetch. Yeah, so the simple [00:29:00] answer there is web transport is the new type of web sockets really. So if you have fetch is really just for fetching URLs, pure http. And then you used to have web sockets. If you wanted to do something custom or something more real time, you would switch to web sockets. And then web transport is I'm gonna have a lot of protocol people angry at me for this, but web socket web transfer is basically web sockets over http three. That's completely untrue. Technically it's very different, but conceptually it's exactly that. So basically you get web sockets over H three, you get all the benefits from http three, but crucially, and this is the big difference, why would you ever want this? You can also do unreliable data over web transport. okay. if you're doing something like multiplayer gaming, You often need unreliable updates, things that don't need to be retransmitted. You can now do that in web transport. That's to me, that's a [00:30:00] big killer feature. Many other killer features in there. But for me that's what makes the big difference. You can do unreliable data in the browser today, but you need to use like web rtc, the data channel, and it works, but it's. It's difficult to set up. Not many deployments have support for that on the server side. And web transport will just make all of this very nicely packaged within the hctp three framework. It should be like a drop in replacement for anything that you would use web sockets or the data channel for web rtc. And even in some cases where you would use fetch right now, you will change to web transport. So super powerful. Super flexible new API coming up. It's so exciting to see these lower level primitives like being reflected in the HTTP protocols, whether that be like in the server list domain. We're in the root protocol domain, and I'm just counting this is amazing, especially the UDP thing. I'm just counting down the days [00:31:00] till we're gonna get age of empires too. Rewritten in the web browser. I'm gonna be so happy when the, when that day comes, yes. And I love that you use Age of Empires too, as an example, because that is still an amazing game. It will always be the, it is like the golden standard. . Robin, , let's close this out. If people are saying they want to go check out http three and they wanna start tooling with it in their day to day, what's maybe a word of wisdom and caution that you would give people when they're stepping into this new technology? Like it could be as simple as this is bigger than you think, or this is smaller than you think. The main thing I would say there is a caution is it's difficult to test. We haven't talked about it today, but there's something called ALT s vvc Alternative Services. How you actually get HCP three to work with the browser is more complex than you probably think. And if you really want to test performance between H two and H three, also very complicated. But if you don't really want to test and you just want to trust [00:32:00] your deployment, that they will make it work, then it's really simple. You just enable it. You just flip the switch in, for example, your cdn, and it just works. And I would say focus on that. Focus on that. Your focus on the easier to reach bits right now and get familiar. Gotcha. exactly. Robin, it was a pleasure having you on and really, doing our second version, our follow up to our last podcast on http three and starting to learn about how we as web developers can start the tool with it and why it's so great. Hope to have you on again when we can talk more about how the protocol's developing among other things. But it was truly a pleasure. If people wanted to keep up to date with you. Do you post anywhere on the internet? Uh, I'm very active on my Twitter, so very active on my Twitter and my LinkedIn. As well. You can find the links close to the recording, somewhere in the show notes. yeah, so probably best to just look for me there. I post on [00:33:00] various different blogs. I don't really have my own blog yet. Gotcha. Robin, once again, it was a pleasure. Thank you for your time. Oh, thank you so much for having me and have fun with H three guys.