Prefetching Overview Demo0:00
All right, next up, let's review prefetching in Inertia 2. You're going to like this one. So let's bring up our demo app, and you'll see for this dashboard route, we fetch a list of projects and we load a projects/index Vue page component. Now, if we have a look at this, of course, we accept those projects. And if I scroll down, we loop over them. And for each one, we display the title and commentCount within an anchor tag. All right, let's see what we get here. And yep, this is what we get. Very, very simple.
Normal Request Flow0:31
And yep, this is what we get. Very, very simple. Okay, so now before we proceed, I want you to think about normally how a request might be made. So here's what I'll do. I will pull up DevTools and open the Network tab. All right, so now, yeah, imagine we are reading the projects, and I come to this first one, and I hover over it, and I'm giving it a read, and then I click on it. And at the point I click on it, then a request is made to the server, we compile the data, a response is returned, and then we render it on the page.
And at the point I click on it, then a request is made to the server, we compile the data, a response is returned, and then we render it on the page. All right, so locally, again, that's very fast. But think about it. Wouldn't it be cool if instead, right as the user hovers over this link here, we can anticipate what they're probably going to do next? And in this case, what they're probably going to do is click on the link. So yeah, wouldn't it be cool if we could just go ahead and fetch the data for that page automatically? And of course we can.
Prefetch on Hover1:27
automatically? And of course we can. I'm going to come back to phpStorm, scroll down to the link tag, and I will add refetch. So now the default behavior is, well, exactly what we just discussed. And I'll show you. Once again, bring back the Network tab, give it a refresh, and now watch what happens. Let's go through that cycle again. I scroll down, I'm giving this a read, I hover over this project, and you can see immediately before I clicked on it, we went ahead and made a request. To fetch that data.
and you can see immediately before I clicked on it, we went ahead and made a request. To fetch that data. All right, so now when I finally do click on it, yeah, it was already fast, but now it's even faster. And I assure you, in a production environment, this will be noticeably faster. All right, so now I know what you're thinking. Is it actually worth it though? I mean, come on. The amount of time between hovering and clicking versus clicking. I mean, is this just single quotes versus double quotes again?
The amount of time between hovering and clicking versus clicking. I mean, is this just single quotes versus double quotes again? Are we dealing with that kind of performance debate? Is it even worth it? And yes, I assure you, it's worth it. They've even done research on this. I believe Google found that for e-commerce sites, for every second you make the user wait, you lose, and I can't remember the figure. Let's just say X.
and I can't remember the figure. Let's just say X. You lose X amount of dollars for every second the user has to wait for a page to load. Yeah, so think about it. Wouldn't it be great if we could just figure out what you're probably going to do? And if you don't do it, that's okay. We can clear the cache and move on. So we do have to be somewhat thoughtful. We don't want to throw this prefetch attribute on every single link unless you have the server resources to handle it.
We don't want to throw this prefetch attribute on every single link unless you have the server resources to handle it. Because if we did that, well then, as a user, process aside, we are just constantly making continued requests. So with that in mind, there are ways to configure this. And I'll show you. When the user hovers over a link for, and to be honest, I can't remember what the timeout is, maybe 200 milliseconds before it's considered an actual hover versus the user just quickly hovering over all of the links.
maybe 200 milliseconds before it's considered an actual hover versus the user just quickly hovering over all of the links. So notice if I give it a refresh and we do it very quickly, bloop, yep, no request is made there. But if I'm intentional and I wait, I don't know what it is, 100 milliseconds, maybe 75 milliseconds. I think that's what it is. At that point, it's long enough that we can assume you're probably about to click on this link. But yeah, if that is too aggressive for you, you could tweak this.
Prefetch on Click3:51
you're probably about to click on this link. But yeah, if that is too aggressive for you, you could tweak this. You could say, well, let's prefetch it only when the User clicks on the link. And now, yeah, this is going to be a smaller performance improvement, but it will still make a difference. Once again, if you think about, as I'm reading this and I click and then I let go, again, that could be a third of a second, that could be half of a second. So now, Inertia is going to detect as soon as you click down and it will make that request versus waiting for you to click up.
So now, Inertia is going to detect as soon as you click down and it will make that request versus waiting for you to click up. Again, these seem like small improvements and relatively they are, but they do make a difference. I promise you, they make a noticeable difference in real life. Now, notice if I hover over it, it doesn't make that request. But the second, the millisecond, I click down, I'm still holding down, by the way, and you can see in DevTools, the request is made. And now I let go and the page loads instantaneously, which is really cool.
Prefetch on Mount4:48
and you can see in DevTools, the request is made. And now I let go and the page loads instantaneously, which is really cool. Now, there are other situations where you might say, you know what, I don't even want to wait for the user to move the mouse or hover or click. I know they're going to click on this link next. So let's just go ahead and prefetch the data when the page component mounts. So here's how we might do that. Let's go to, yeah, so what you see right here is the Show component. So I'm going to switch over to that, Show.
Let's go to, yeah, so what you see right here is the show component. So I'm going to switch over to that, show. And now we have this link to go back. And maybe we've decided if you're viewing one of these projects, the next link you are very, very likely going to click is back, right? So why don't we just go ahead and prefetch that data for you? Here's how. Once again, I'm going to say prefetch, but I'm going to set it to mount. So now here's what's going to happen.
but I'm going to set it to mount. So now here's what's going to happen. I will once again bring up the network tab. And now if I refresh this page, you will see, yeah, we automatically fetch the dashboard component the second this mounts. So now, yeah, you'll see as I hover over back, it's not going to do anything because it already prefetched the data. And of course, now it's cached in the browser's memory for, by default, 30 seconds. So if I click on this, once again, it is so fast. It's really cool.
Caching and Stale Rules6:11
So if I click on this, once again, it is so fast. It's really cool. Now, further, we can configure how we cache things. So why don't we bring this back to the default? And I could say cache this for whatever I want. Like I said, by default, it's 30 seconds. But if you want that to be a little more aggressive or a little slower, you could do one minute. You could cache it for only five seconds. And what this effectively means is,
You could cache it for only five seconds. And what this effectively means is, how long should that data that we've requested be stored in the browser's memory before it's effectively discarded, before it's expired, and we would make a new request? So I'm going to set this to five seconds just to show you how it would work. And let's give it a refresh, open up the network tab. And now if I hover over this, it's not working. Oh, I'm sorry. We were on the Show component.
Oh, I'm sorry. We were on the show component. OK, that's fine too. Let's click over here. And once again, let's give it a shot. Sorry about that. Now if I hover over back, we fetch the dashboard. But let's just clear this out and wait three or five seconds for that cache to be cleared. And now when I hover a second time, you'll see, yeah, the cache has expired. It has cleared.
And now when I hover a second time, you'll see, yeah, the cache has expired. It has cleared. It has been discarded. And now we will make a brand new request. That way we always have the most current data possible. Now, you could even take this further in situations where you need maximum flexibility or configurability. You would pass a tuple here. If you're not familiar with tuples, just think of it as like an array of two values that always go together.
If you're not familiar with tuples, just think of it as like an array of two values that always go together. Think of it as an array of two items that are married, where one goes, the other goes. And it doesn't make sense for one to be there without the other hand in hand. That's one way to think about it. Or just an array with two items that you pass places. And we call it tuple because it's a fancy thing that we do. I don't know why we do it. We just do it. Anyways, let's continue.
We just do it. Anyways, let's continue. We could say, let's provide two values here. The first value will be the normal cache period. So we're going to cache this for 30 seconds. Next, we're going to have a second value that is beyond the stale date. So let's see if I can explain this pretty clearly because it can be a bit confusing. All right, so the first item here, 30 seconds, this is our cache period. How long are we caching that page response? But what if you make a request at 35 seconds or 40 seconds?
How long are we caching that page response? But what if you make a request at 35 seconds or 40 seconds? Well, traditionally, you just have to pay that penalty, right? Sorry, the cache has cleared. You have to download all of that and wait for it. You don't get any kind of cache bonus in terms of performance. However, if we take this approach, there's a stale period where we say, all right, well, this data is a little bit stale, but I'm still going to give you a fast page load. And behind the scenes, we're going to clear and refresh that cache so that on the next request, it once again is instant.
And behind the scenes, we're going to clear and refresh that cache so that on the next request, it once again is instant. So it's a way to get around situations where you have to pay a penalty when the cache has cleared. Between 30 seconds and one minute is the stale period. The data is a little bit stale, but we can live with that. Let's return that stale data to the user, refresh the cache, and then merge that in. And that way, you don't pay any penalty. And that's a good way to go. But keep in mind, I think this would be for more advanced projects.
And that's a good way to go. But keep in mind, I think this would be for more advanced projects who really need a fine level of configuration. For most projects, I think you could probably stick with the default that Inertia provides, which is cache it for 30 seconds and then clear. And you're probably good to go. All right, so of course, there are some other options. You can programmatically configure prefetching, but I'm betting that 95% of the time, all you will need to do is visit your site.
but I'm betting that 95% of the time, all you will need to do is visit your site and consider what are the links that the user is most likely to click on and be thoughtful here. So for example, at Lerika, if I take a look at one of our Series pages, we got a lot of links here, but I can anticipate that the user is very likely going to click on this link. So if I wanted to, and if it's worth it to me, when the SeriesPage component mounts, I could go ahead and prefetch this link.
when the series page component mounts, I could go ahead and prefetch this link. Alternatively, I can have general assurance that you're probably going to click on this and I could prefetch it when you hover over the button. Or finally, for any of these links down here, I could say, well, I don't know if you're going to click on these, but I could say prefetch on click. And that way, I'm not being too aggressive, but I am trying to get a small performance boost.
And that way, I'm not being too aggressive, but I am trying to get a small performance boost. The second you click on any one of these, we will instantly begin fetching the data for the episode page. All right, so that's something to think about. Let me know your thoughts.
