This episode is for members only

Sign up to access "Livewire Performance" right now.

Get started
Already a member? Sign in to continue
Playing
06. Deferred loading

Transcript

00:00
Deferred loading can be really useful if you're fetching data either from your own application or an external API, which takes a little bit longer to load.
00:08
Ideally, you don't want to stop your initial page load from rendering before that data is available. So what we're going to do is look at creating a fake API that returns some data, maybe about a user's subscription. So let's say you had a specific Livewire component, which fetched subscription data from Stripe. And you wanted to display that, but that request might take a little bit longer.
00:32
So you want to get the page loaded as quickly as possible. And then from there, you want to wait till that data comes back and perhaps show a loading indicator. This can be really useful for just generally speeding up your page. So we're going to go ahead and create our component in here, which is going to handle this.
00:49
Let's go ahead and use Livewire Make. And we're just going to call this subscription details. So let's create that out and we'll render this out on our dashboard subscription details. And we're going to go ahead over to the subscription details component. And we're going to make a request here to an API.
01:08
Now, we're not going to go ahead and hit the Stripe API. So I'm going to go ahead and create out a fake endpoint in here. And that gives us the ability to use something like sleep inside of PHP to slow this down. So let's go ahead and create this route out and we're just going to do slash subscription here.
01:25
And inside of closure, let's go ahead and return some data. So I'm just going to use our response helper, return some JSON data, and in here we'll just say subscription and then details. So just something that we can use. What we're then going to do is use sleep
01:43
or use sleep to sleep this for two seconds. So we're going to get a two second delay when we hit this API endpoint. We can test that out in the browser by just coming over to API slash subscription and you can see that we get about a two second delay before that data rolls in.
01:59
Okay. So now that we've got this, we can actually make a request this over in our subscription details component. Now, because this is an API endpoint within our own app and we're making a request to our own API endpoint, we're going to do things slightly differently. Typically, you would use the HTTP facade to make external requests like this
02:18
or, of course, some sort of library that is provided by the service you're using. But for now, we're going to go ahead and just use root to go ahead and dispatch this to actually get back that API information. So we're going to go ahead and make sure that we import the root facade in here.
02:35
Make sure that's the facade. And then we're going to go ahead and make a request or create a request to our own application, which is API slash subscription. And then we're going to choose how we're going to get that information, which is just get. And with request, we want to make sure we just pull this in from illuminate HTTP request.
02:54
So now we can pass this data through to our component and let's do that properly. And of course, we can display out this information over in the subscription details blade file. So let's just dump this out on the page. It's not going to quite look right because we're just messing around.
03:12
But you can see now that when we refresh this, the whole page takes about two seconds to load and then gives us back the body that we need with some other information. But we can ignore this because we're making a request to our own API. So this is a massive problem because when we refresh the page,
03:28
we've got to actually wait for that data to come through before the entire page is loaded. So we're going to switch this up. So we defer this and load the component instantly. And then we wait for this or we request this information. Then we wait for it to come back and show it when it's available.
03:46
So let's look at how we can switch this component up to make that happen. So the first thing that we're going to do is create out a public property inside of this component, which tells us when this data has been loaded or when it's ready to start loading in. So let's just give this a really long name just so it kind of makes sense.
04:05
ReadyToLoadSubscriptionDetails. That kind of makes sense. And by default, that's going to be false because we don't want to do this until this is specifically or explicitly set to true by ourselves. Now to explicitly set this to true, we need a method to go ahead and change this value.
04:24
So let's go ahead and create out a method in here called LoadSubscriptionDetails. And all that method is going to do is set that property, ReadyToLoadSubscriptionDetails, to true. So as soon as we're ready to load this information, we call this method and then this becomes true. So at the moment, it doesn't sound like we're getting very far,
04:46
but let's just go ahead and do this within that base component. So over in SubscriptionDetails, we have this initialize or init method or functionality that we can use to call a specific method when this has initialized. So as soon as this component initializes,
05:03
that is when we want to trigger the loading of our SubscriptionDetails. Now let's just dump out that value inside of this template. So ReadyToLoadSubscriptionDetails. And let's go ahead and get rid of the subscription output here and just see what happens.
05:17
So I'm also going to go ahead and comment this out because that's going to cause our page to have a slight delay and let's see what happens. I'm going to refresh this and yeah, undefined variable. That's just because we've commented out. Let's actually get rid of it.
05:31
And let's give that a refresh there. So now it says 1. So as soon as this component initializes, this value is now set to true or 1 in the case of dumping it out in Blade. So now what we can do with this, let's just bring back our subscription here, get rid of this.
05:45
We can go ahead and only do this when this value is true. Now there's loads of different ways to do this. We're just going to go by the way the docs show us to do this. We're going to grab what we want to do and we're going to pass this directly down as subscription,
06:00
but we're going to add in a ternary to only do this when we're ready to load them. So we're going to say this ReadyToLoadSubscriptionDetails. If we are ready to load them, then we're going to go ahead and pass this result down to subscription. Otherwise, we're going to go ahead and just return null, an empty array, an empty collection,
06:20
anything that makes sense for the kind of data that you're working with. Now don't worry if this doesn't make too much sense at the moment. We'll run through in just a second, but let's just see what happens when we go over and refresh the page.
06:30
So we get an instant page load or a quick enough page load as we would normally see. Now I've been sat here refreshing the page over and over again, but what we've not seen is when this is available, it's going to be shown. So if I come back over now, you can see it's shown.
06:44
So I'm going to refresh the page. We get an instant load. Two seconds later, when that data is available, e.g. over here, when it's available or when this has been set to true, this is then going to wait and then it's going to be passed through to subscription.
07:00
So with this in mind, what we can effectively do is wrap an if statement around this. So we can say if subscription. So is that data in there? E.g. is it not null? Then we want to show the subscription and then we can add an else and we can say loading.
07:16
So this is when subscription, the value that we're passing through here, is set to null. So let's go over and give this a refresh and you can see we get that loading indicator. And then when that data does roll in, we see all of the details that we want. So let's just recap really quickly because when I first saw this functionality,
07:32
it took me five minutes to kind of wrap my head around what was actually happening. So the first step is over on subscription details. When this component initializes, we call this load subscription details method. What that's going to do is set this original false value to true.
07:50
Now that's important because this will originally be false. So we don't want to load this in this ternary until this is set to true. So as soon as this toggles over to true, then we start to make the request. But by this time, the component was already loaded.
08:08
So we are initially loading the component and then toggling this to true. And then that means that we can control when we want to make this request. And that request, of course, is only going to be made after the component has loaded. We're effectively, we're not really, but effectively making an AJAX request to this data.
08:24
So once that component gets updated, this is the initial state of it here, this first request to dashboard. And then Livewire will automatically re-render once it has the new details in there. And there are loads of different ways that you can trigger this.
08:39
So, or loads of different reasons you might want to trigger this. You might want to wait until you click a button, which is just going to be a case of calling a method and either doing this or just setting some data, setting some data based on this request.
08:54
But in our case, what we want to do is load the component, show a loading indicator, and then once that data comes back, we can display that information out. So we get an instant page load, a loading indicator, and then finally the details rolling in.
11 episodes1 hr 22 mins

Overview

Building powerful apps with Livewire is a breeze, but as your app grows, you may run into performance issues. This series covers tips and techniques to keep your Livewire apps speedy.

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

Episode discussion

No comments, yet. Be the first!