Playing
09. Prefetching

Transcript

00:00
Inertia has added prefetching, which is probably one of the easiest ways to speed up the perceived speed of your application. What we're going to do here is take a look at the most basic usage of this by tying this to a link component to preload the data for the next page that the user is potentially going to click. Then we're going to look at more advanced usage of this using programmatic prefetching in a list where we want to load more.
00:27
We could also use that for pagination, anything where you have a bunch of records and you want to load more, either by pagination or some sort of infinite scroll. So let's cover the basics first. Before we start, we're going to go ahead and create out a new route for this. So let's not even bother with a controller here. Let's just go ahead and copy over this dashboard route and create this out as a user's route so we can see some information here. Let's go ahead and render out a user's page and we'll pass some data down.
00:56
Now, what I'm going to do here is I'm going to make this appear slower than it actually is just because the data that we're loading from the database is going to be pretty quick. So let's go ahead and use a closure for this. And we're going to go ahead and just sleep for one second just to simulate this being a little bit slower. And finally, we'll just go ahead and return all users here. So let's just say user and get. OK, so if we come over to resources, JS and pages, let's go ahead and create out this page in here, which we're just going to call users.
01:27
And we may as well just go ahead and steal the dashboard template just to make this a little bit easier. OK, so let's go ahead and set the title here. Go ahead and set the header. And what we're going to do is just dump out all of the users that we're passing down onto this page. So let's bring in define props here, pass down our users as an array and we should be good.
01:51
So let's go over to the users page and take a look at this. And there it is. Pretty straightforward. And we get that one second delay to load that data in. OK, let's tidy this up by giving this the name of users. And then we're going to hop over to the authenticated layout and we'll add this to the top navigation.
02:10
So let's go and add in a new level navigation link in here for this users page. And the goal here is to preload this data before the user even clicks on it. So that one second delay that we've simulated doesn't quite seem like we have a one second delay. So let's go ahead and add this to our navigation and let's take a look.
02:31
OK, so if we start over on dashboard, of course, when we go ahead and click on users, this is going to take around a second and then it's going to show the data. Let's go ahead and look at the easiest way that we can prefetch this data. And that is simply on a link element within Inertia, which is actually behind this nav link.
02:49
We'll take a look at that in a second, is to use prefetch. Now, nav link is just part of Laravel Breeze. Behind this, it does use the link components. You can use this directly on a link component. Or if you want the props that you pass in to fall back and go on to the component inside of here, that's going to work as well.
03:08
OK, let's go over and try this out. So I'm going to go and go over to the dashboard. Now, what I'm going to do is hover over users and then I'm going to click on it. Now you can see that was almost instant. What's happened here is as we have hovered, and that's the default JavaScript event,
03:24
this has preloaded this prop in the background and all the other data required by this page in the background. And then when we click on it, that data is cached and ready to display on the page. We can demonstrate this by just opening up our network tab. So let's pull this across to here and let's open up our network tab and filter by fetch XHR.
03:45
So I'm going to head over to the dashboard and this might not work because of caching. We're going to cover that in just a second. But when I hover over users, you can see that behind the scenes that request was made to preload that data. And if we have a look at this network request, you can see that, sure enough, under the props, this has loaded all of the user data for us.
04:05
So really, the easiest way to get started with prefetching is just to add the prefetch prop to any of the pages you think your users are likely to navigate to most often, or the ones that are going to be slightly slower. Of course, it's more important to optimize for speed before you start to prefetch. It's not something that you can just use to get away with having a slow application,
04:27
but it does really help improve the perceived speed of your application. OK, so I spoke a little bit about caching. Now let's take a look at how we can adjust the cache duration of this. This data needs to be cached because otherwise it's not going to be available when we hit the next page. Let's go ahead and say cache for and let's choose a really low amount of time here.
04:48
So let's say one second. What that means is when we go ahead and hover over this and then go ahead and click on it, that works. When we come back to this, though, it's going to make the same request again because we've got a very short cache time. Let's go ahead and adjust this and we can use values like one second, 30 seconds. We can even use things like five minutes. Or if you want to provide a millisecond amount,
05:08
you can go ahead and bind in that millisecond amount. So this would be, of course, five seconds. Let's go ahead and switch this to five minutes and let's just take a look at how this works. So we'll pull up our network tab here, pull this in a little bit and let's have a look. So I'm going to hover over users. I'm going to click on it. By the time I've clicked on it, that data has been loaded.
05:28
When I head back to dashboard and hover over users again, notice that we don't get the same network request. That is because this data has now been cached. Now, of course, that can create an issue. If we do go over to, say, Tynker and go and create our user. So let's go ahead and use Tynker to make a new user in here, just using our user factory.
05:52
That's going to cause a problem. So let's create our user and let's go over to dashboard, then head straight back over to users. You can see that because this data is cached, it is not up to date. So there are several caching strategies that you can use for this. You can either lower this to the amount that feels comfortable for the data that you're working with,
06:10
or you can use more advanced caching strategies like using the stale while revalidate pattern, which involves passing into our cache an array of values that we want to be the first considered stale values. So, for example, let's say 10 seconds and then the last value, like five minutes. And then after this time frame will be when that data is refetched.
06:31
Now, we have a really good episode over on the new in Laravel course about this caching functionality, since it's pretty new to Laravel. And I go into a lot more depth there with some examples. I'm not going to repeat that here, but you can go ahead and check that out and you'll understand how the stale while revalidate pattern works. OK, let's pull our cache back to a value like something sensible.
06:52
Let's just say one minute and let's look at some of the other things that we can do with this before we go on to look at a more advanced usage of this. So another thing that we can do is customize how the data is prefetched. So at the moment, by default, this is on hover. We know it's on hover. And actually, I'm going to set this down to one second just so we can keep demonstrating this.
07:16
So we know that when we hover over any of the links that we've provided prefetch to, that's going to go ahead and preload that data. But what we can do is we can customize this by passing an argument through to the prefetch prop and not just setting this to true. So that is going to be any of the events like mount, hover, whatever you want inside of here. Now, let's change this to prefetch mount and see what happens when we just land on the dashboard.
07:42
I'm going to give this a refresh and you can see that behind the scenes, the data has already been prefetched. We've not even had to hover over this. But of course, when we do click on it, it's going to be ready. If the cache is not stale, because obviously we have a very small cache duration here. So why would you want to prefetch something on mount of the page?
08:04
Well, this could just be a page that is perhaps very slow and you can't improve the performance of it for any reason. For example, if you're hitting an external API or it's a very popular page on your site and you know that the majority of your visitors are going to be visiting that page. So let's say that, for example, we had an app where users were the central point of this application. We might just want to always use a prefetch mount to always load that data in.
08:32
Now, what you can also do is you can go ahead and provide multiple options here. And at first, this might seem a little bit confusing, but let's say that we wanted to prefetch on mount and on hover. Now, why would we want to do this? Let's go ahead and bump the cache duration up for something like 30 seconds. And let's take a look at how this works. So let's give the page a refresh.
08:53
And we know that that's being prefetched in the background. When we hover over this, this will only go ahead and refetch this data if the cache is stale. So if your users do land on the page and you've decided to prefetch this data on mount, this data might be out of date by the time they actually click on it. So, for example, when we re-click this or re-hover over this because we've chosen hover as the other option, this will then go ahead and prefetch this again. So really, it depends on your strategy and you'll have to go ahead and figure out what works best for your app.
09:25
OK, so I think 30 seconds have passed. I'm going to go ahead and hover back over this. And you can see that data is reloaded again as the user goes to navigate to this page. So by combining something like mount and hover, you always know you're going to get more up to date data because the cache has expired and you're going to prefetch that again. So, again, you're basically balancing out the cache with how fast you want this to fail.
09:47
So go ahead and play around with this for your own app. But this is the most basic usage here that we can think of, just applying this to links. Now, behind the scenes, a link component practically uses Inertia's router. You can provide the majority of options that you would usually provide when you're programmatically using the router. And prefetch is no different.
10:09
So what we're going to do is just get rid of these two in here. And I'm just going to go ahead and add them as a comment here. So we have them handy if we need them later. And we're going to go and look at a slightly different example. So let's go over to our web routes and let's create out a new route in here called users load more.
10:30
Let's also change the component we're using here. Let's create a new component just so we have a reference to the old one. And we'll go ahead and also keep in this sleep as well. But this time, what we're going to do is we're going to paginate this data. So let's paginate this by, say, five. And just before we forget, let's go ahead and create out a few more users in our application. So we'll just create 100. So we've got plenty to play with.
10:55
OK, so the goal now is to look at anticipating and preloading a next set of data like you would in pagination or in some sort of load more or infinite scroll functionality. OK, so we've got our new endpoint just here. Let's go ahead and create out a new component for this. So we'll create out a view component in here called users load more. We'll basically just grab what we have from our users because it's going to be very similar.
11:20
And we'll pop that in there and let's head over to the browser over to that users load more and see what we get. OK, let's change that up and we should be good. Great. So, of course, we get that one second delay, but what we now want to do is build in some functionality where we have a button down here to load the next set. Now, let's assume that every time we loaded the next page or the next set of data, this delay is going to be about a second.
11:45
Again, not going to happen with your database, but if you were using some sort of external API or had some sort of slow running process and you wanted to load a next batch and you knew it was going to take a while, then preloading programmatically here is going to work nicely. OK, so under users load more, what do we need to do? Well, let's wrap this data here in a div just to keep it out of the way. And we'll just create a really simple button down here to go ahead and load more.
12:12
In fact, the example we're looking at here is kind of more like load next set rather than load more. We're not going to append this on. We've already covered merging props in this course, so you can go ahead and combine this with merging props if you want to. We just want to kind of go to the next page. OK, let's go ahead and hook this up.
12:30
So let's say V on click and let's say load more and let's go and implement this just up here. And again, we'll just do a manual router request to get this data. So we want to set this as an object because we're now going to have a pagination object in here. And let's pull in our router and let's go ahead and reload this page with some data.
12:57
So let's take in the data here. That's just going to be the next page. So let's set the page here to our props. So we'll grab them props out here and we'll say props dot users dot current page and we'll just add one. Again, this is going to be a really basic example, but it will give you an idea.
13:16
OK, let's make sure we pull in our router here and we should be good. So what we should now be able to do is click to load the next set. We'll get a one second delay, but you can see the next set of data is now being loaded in. So, of course, we've got that one second delay.
13:31
So what we want to do here is we want to programmatically use prefetching to prefetch the next set of data. So for this, if we were working with a button, this isn't an inertia link component. It doesn't really make sense to do that. We're going to say V on mouse over or mouse enter.
13:50
We are going to prefetch our next set of users. So let's go ahead and create this method out here and look at programmatically doing this. So to programmatically prefetch this data, we're again still going to use our router. But this time we have a prefetch method available.
14:11
We go ahead and choose which page we want to preload. So in our case, it's users. And what do we call this? Load more. So let's say load more. And then we just pass down the method. First of all, pretty important. We need to know how to make this request.
14:25
But then any data here. So the data that we want to pass down is going to be the next page. So effectively, what we're now doing here, and let's just pull this down a little bit. So it's a little bit easier to see what we're doing. We're effectively now saying that we want to preload the next page as the user hovers over the load next set button.
14:48
Let's try this out. So I'm going to go ahead and open up the network tab so we can see what's going on here. And let's just take a look. So let's actually bump the page number down so we can see what we're doing a little bit better. So let's say paginate three. OK, great. So let's go ahead and hover over load next set. And we get an error here.
15:09
Yeah. So we actually need to provide the cache for value into this. So let's go ahead and do that now. So as the third argument to prefetch, remember, this object here is what we would usually pass down to our router. We need to provide how long we want this to be cached for. The docs don't actually show this at the moment. Let's go ahead and cache that for one minute. OK, let's go and try this again.
15:30
So let's make sure we're in our network tab here and let's get rid of our console. Let's hover over load next set. Remember, each of these requests are now going to take a second. And you can see that page five has been loaded in. I'm on page four. That means now that we've preloaded that page, as soon as I click on it, that data will then be available.
15:48
Now, it didn't look like that actually worked. I have a feeling it's because rather than reload, we want to manually visit this page. So let's go ahead and just work this out. Users and load more. And that should be good. As long as the data matches up to what we have here, that's going to be cached and then served.
16:07
OK, so we're visiting this when we load more rather than reloading. But we're prefetching the next page as we hover over that button. Let's try this out. We'll go back to page one to test this. OK, so when I hover over load next set, we should get page two preloaded. By the time I click on that, that data is already there and you can see it is loaded in without another request that data.
16:29
I'm going to make this a bit smaller just so it doesn't keep jumping up. And let's try this again. We get page three loaded immediately. And the same again with page four. And that data comes back in. So effectively, what we can do with this programmatic prefetching is anticipate for lists of data that we're loading in like pagination or loading a next set of data.
16:51
As the user hovers, we can start to load that data in the background. We don't exclusively need to use this with the link component. So there are a couple of other things that you can do around prefetching, like flushing this data. For example, you could use router and flush all.
17:07
What it will do is it will clear out the cache for all of the prefetch pages that you have. You can also flush particular pages as well. So, for example, if you wanted to flush the request that we've made here, this prefetch request that we've made here, you're going to need to provide in the URL like this. And then you're going to need to provide the exact signature that you made here.
17:32
So if you, for example, wanted to clear out all of the pages or specific pages, you would need to make sure this data matches up so it can flush this out properly. I can't really see a need to want to flush this in most cases that you would use prefetching, but it's all there if you need to do this. I think the two most common things here are to prefetch links like we've already seen over in our navigation when we hover and also programmatic prefetching when we're doing things like loading more or navigating through pagination. That's pretty much prefetching. Super helpful if you use it carefully.
9 episodes1 hr 27 mins

Overview

With the release of Inertia v2, let’s cover everything new — now and into the future.

Each episode of this course will cover a new feature or significant change, so you’re ready to adapt and introduce new functionality into your Inertia-powered applications.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!