Playing
05. Loading more with a button

Transcript

00:00
Okay, we know that this isn't the most performance solution overall, we already discussed that in the introduction, but what we're going to do now is look at a really naive approach to infinite scrolling. And that involves first of all going ahead and creating out a button, we're just going to use that button manually for the moment before we get to the point we actually observe the scroll,
00:22
and we're going to increment the per page amount, and we'll see just by looking at our network tab how slow this is. So we need to be really careful with this. The first thing that we're going to do is go ahead and create out a per page value in here,
00:36
let's set that to 10 and then we'll reference that from here, so this per page. Now if we head over to the article index, let's create a button down here which goes ahead and loads these in or increments this. So we're just going to say load more, we'll just keep this button really simple for now.
00:53
And then when we go ahead and click on this, we want to increment that per page value, and then we'll take a look at our network tab and see how slow this is. So we'll go ahead and create out a method for this. So let's say load more, we'll just keep this really simple for now.
01:08
And with this we're just going to go ahead and say this per page, and we're going to set that to this per page, but we're going to go ahead and add 10 on. So let's go ahead and invoke this and see what happens. So load more, and we can head over and test this out.
01:24
Okay, so I'm going to click this and sure enough it does work. So you can see that pretty much we have infinite scrolling minus the actual scroll action, and this is working. But let's head up to the very top here, go ahead and open up our network tab,
01:40
and we'll just filter this by XHR fetch request, since that's what Livewire is doing behind the scenes. So let's hit load more, we get 33.8, 33.3. Let's keep going here and go all the way down to the bottom.
01:57
And we might not have enough records, but this is increasing in speed every single time, which is a massive issue. So the further we get down here, the slower this is going to get basically. Now this itself isn't the main issue.
02:13
The main issue is what we're doing when we go and increment the per page, is at the database level we are re-requesting 100, when we get to the bottom of the list, 100 items from here, when we don't really need to request 100 items from the database.
02:32
This is going to end up incredibly slow, particularly if you have a lot more data in here. So what we're going to do is change this around, so we use a collection instead, and we push onto that collection. So we'll go ahead and get rid of what we've already done,
02:47
because we're not going to go with that approach. This is just a really good demonstration of how you might go ahead and approach this. So what we want to do, the first thing is take out the article reference here that we're grabbing all these records from,
03:03
and we're going to put them into a computed property. And the reason for that is we want to be able to access this from inside of our component, and extract out the next set of results to push to a custom collection. So let's just see how this looks.
03:17
We'll go ahead and create out a paginator, which technically is returning a paginator to us. And let's go ahead and return that. We need to mark this as computed,
03:26
so we're going to go ahead and use the computed attribute just here. And we're good. So this is going to break what we've already got, but that's absolutely fine. We can go ahead and get rid of this now.
03:38
And if we go ahead over here, it's just not going to work, because we've got an undefined variable articles, but that's fine. So the whole goal here is to go ahead and within our live wire component, store a collection of our own custom articles that we push to.
03:55
So we'll go ahead and put in the illuminate support collection class in here. And what we want to basically do is fill these articles up with the first set of articles. So we want to load 10 articles. And then every time we press a load more button,
04:12
we want to go ahead and push to this collection. So let's go and create out the mount function within live wire to do some setup. So the first thing that we're going to do is initialize this collection. So we're going to go ahead and assign articles to be a collection like so.
04:30
We want to go ahead and now reference these articles within our template, which should now work because technically we've just replaced out the variable with something that we're already passing down. And once we have initialized this, we want to load the first batch into here.
04:47
So we can already start to create our method in here, which will load the next set of our articles. So let's call this load. We'll just call it load more.
04:59
And inside of load more, we want to go ahead and increment the page because we need that to be able to get the next set. But we want to push to the articles. So we're going to say this articles.
05:10
Now Laravel collections have a push method, which allows you to push another set of data onto this to sort of merge in. So we're going to go ahead and say this articles push. And then we're going to grab the results from the paginator,
05:24
which we now have as a computed property just down here. So we're going to go ahead and say this paginator and get collection. So get collection will return to you a Laravel collection of arrays with that data in. But we can't just push this in.
05:44
Or we're going to end up with a collection inside of a collection. So we're going to use the spread operator to spread this out. OK, so now basically, if we just call load more when we mount this method, so let's just say this load more, what is going to happen?
05:59
Well, it's going to go ahead and grab the first set of results from the paginator. That is 10 items. It's going to push them into the articles collection. And then these articles are going to be displayed on the page.
06:14
So effectively, by doing all this, what we've done is just ended up what we had before. We have the first 10 articles on the page. Now though, when we call load more, we can increment the page and push only the next 10 items to this collection.
06:29
So how do we do this? Well, let's go ahead and down here, after we have pushed these articles, go ahead and increment the page. So let's say page.
06:38
And we'll just assign this to page plus 1. So the next time we press load more, well, the first time we press load more, this will be incremented to 2, which means that the second time we do this, when we extract these results from the paginator, this paginate page will be 2.
06:56
So we'll then get the next set of results. And we'll push that next set of results to our article collection, effectively loading more, but only querying 10 articles at a time from the database. That's the problem the first solution didn't address.
07:11
It would just load 100 records in one go if we were at the last page. This is only just doing 10 at a time and then pushing on to our collection that we've created. So now that we've done this, we can just invoke load more, like we did from our article index, which we already have here.
07:27
So let's try this out. So I'm going to hit load more. And there we go. Sure enough, this is working.
07:34
Now, we might not be able to see the speed difference over in our network tab. But let's just take a look here. Because the database query for this isn't particularly slow. But we will definitely see a database query time improvement with this.
07:51
So you can see that the time is still jumping up. Because like I said at the start of the course, this isn't the most performance solution. But it's better from a database point of view.
08:00
If you had 1,000 records in here, you wouldn't want to load 1,000 records from your database in one go. OK. So that is all working nicely.
08:08
We've now come up with a solution that's not hitting the database too hard. But it's still slow. We know that it's still slow. We're going to have another course on how to make this really, really fast.
08:18
But this is good. It is working. We can hit load more. Now, just before we go, let's go and just sort out this load more button.
08:26
Because when we get to the end of our article list, we obviously don't want to show this load more button. So let's go and just have a look at our article index again. We know that we've got this paginator in here, which returns a paginator instance.
08:40
A paginator instance within Laravel has a method on it called hasMorePages. So what we can really easily do now we're working with this computed property is say this paginator. And we can say hasMorePages.
08:54
If it does have more pages, then, of course, show that we want to load more. Otherwise, it won't do anything. So if we head over here and yeah, let's have a look at this pages. And we're good.
09:06
OK. So now when we load more here and we go all the way down to the bottom, pretty boring because we have a huge amount of records in here. You will see that when we get to the end, we do not show load more again.
8 episodes 35 mins

Overview

Adding infinite scroll to Livewire can be tricky. Let’s implement a really easy (but slow) solution, and then look at a better way to continuously load more records as we scroll the page.

We’ll also include a really easy way to implement the Intersection Observer API with an Alpine plugin, and add some enhancements to create a nice, smooth scrolling experience.

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

Episode discussion

No comments, yet. Be the first!