02. Passing basic prop data instead of huge objects


The first performance tip we're going to look at probably has the biggest impact on the memory usage of our app just here and also the request duration, of course, based off the memory usage.
And that is how we pass data through to LiveWire components. Now we're going to do a little bit of setup here by creating out an employees table, which we can use to generate a huge list of employees or any fake data you want. And we're going to iterate through and pass the prop data through to a LiveWire component in that loop.
Now this might all not always be necessary, which we're going to take a look at later, but we're going to see how this impacts page performance and how we can remedy it. So let's go ahead and make out a model. So we're going to go and make an employee model here.
Let's generate a migration and a factory alongside of that as well, so we can generate out some fake data. So let's first of all go over to the create employees table and we'll go and add in some columns here that we might want to see for an employee.
We're going to add a few in here just to kind of drill the idea in. So let's go ahead and add a name for the employee, an email address, and let's also add a phone number. And to finish off, let's just add an address in here. So we've got quite a bit of data that we could potentially pass through to a component to show an employee.
So let's go ahead and run php artisan migrate and that's that created. Okay, so we're going to head straight over to the employee factory and we're going to generate out some fake data for this employee. So for the employee's name, we'll go ahead and use faker to generate a name out.
For the email address, we'll do the same. So let's swap that over to email. And of course, we've got a phone number in there as well. So let's add in our phone number.
That's just going to call the phone number method. And then finally, we've got that address in there. So let's change that over to address. Great. So we've got quite a bit of data in here being generated.
Let's run php artisan tinker so we can use that factory to generate out a load of records. So app models and employee. Let's grab the factory instance for that. And let's generate out a thousand of these just so we've got plenty of data to play with.
And let's go ahead and create them out. So that should have created a thousand records over in our database table. Let's check it out. And there they are.
So we've got plenty of data to play around with. So we're going to create two components. The first component is going to grab the list of employees and then inside of that component template, it will iterate through them.
And then we'll create a second component to pass each of them employee objects through to a sub live wire component, which will be that kind of line row. Imagine we have a table of employee data. So let's go ahead and use php artisan live wire make.
And we're just going to create out an employee list in here. We'll also create an employee list item, which will be the thing inside responsible for showing each of the employees. So over on dashboard.blade.php, let's add this in here first of all.
So employee list. And if we open up the employee list component, this is where we're going to show this list of employees. So let's just say employees employee get.
And of course, you probably would use pagination here. But just so we can demo this out, we're going to pass all of the employees through to here straight up. So let's go ahead and make sure we pull in the namespace for the model.
And we're good. So in the employees list component, we can now iterate through each of them. So let's say for each employees as employee. And let's end that for each.
And let's just dump something out on the page. So let's say employee ID. So we should just get a bunch of IDs inside of here. OK, so let's go over to our employee list component
and actually make sure we pass that through as employees. And there we go. We've got all of the IDs for each of them employees. Great.
OK, so inside of the employee list in here, what we now want to do is render out a LiveWire component with that employee list item. And this is common if you had actions inside of a LiveWire component
which you needed to use. If this was just to display a list of employees, you wouldn't use a LiveWire component here because it would just be a waste of using a LiveWire component.
But what we want to do eventually is pass each employee through to this. And then maybe inside of this list item, you had actions to delete the employee or something like that. So over in the employee list item,
this is where we want to show out some information about each of the employees. So we need to pass this through first as a prop. So on the employee list, we're going to go ahead and pass the employee through here. So let's pass that entire object through here,
which is what we're looking at in terms of performance. And then under employee list item dot php, we can accept that in via a property. And that will be automatically available in our template.
So over employee list item dot blade dot php, we can now just start to output information about that employee. So let's just say for this, we only needed two bits of data to be displayed in this component,
the employee ID and the employee's name. And we didn't really care about much of the other information. If we give that a refresh, you can see that this is outputting all of them employees.
And of course, we have lots and lots of records here. So we have a high memory usage and also a high request duration. But the point of this is we can actually improve this. If you did want to output a thousand employees,
or if it was only a hundred, it doesn't really matter. We can make an improvement to the way that we pass through data to this component. So let's look at an alternative to get this memory usage for all of the employees right down.
So if we come over to the employee list, at the moment, what we're doing is we're passing an entire object through as a prop. So that is a huge amount of data, most of which we don't need is being passed through to this kind of sub component.
Now, if we just open up Laravel Debug Bar and go over to the Livewire tab, you can see that for each of these employee list items that are rendered out, if we just click on this, you can see that under the data, this employee is the employee model, which has a huge amount of information.
We've got all of this data, which we're not really using. So that's the entire model being passed through. Of course, that's going to increase the memory usage and then the request duration of the page.
So let's just say we did only need the ID and the name of each of these employees. What would be the solution? Would be to not pass the entire object through if we don't need the entire object. It would be just to pass the information that we need.
So for example, we could just pass the ID through employee ID, and then we could just pass the name through employee and name. So this isn't always going to be the case. Sometimes you'll want to pass the entire model through,
but even if you didn't and you just had the ID, that means that if you did have an action inside of each of these, you could just relook up the model using the ID and then you could perform an action on it.
And we'll take a look at that in just a second. So let's go over to the EmployeeListItemLiveWireComponent. And now we can just change this over to ID and name. And that will be available in EmployeeListItem.
So let's open this up and just switch these over to ID and to name. Great. So I'm going to come straight over here and we're going to check out this memory usage and the request duration.
We're still outputting the same amount of employees, 1000. But look how much quicker this is going to be. And of course, the public property ID is reserved. So we're going to go ahead and just change this over to EmployeeID.
That kind of makes more sense. And let's keep the same convention here and say EmployeeName. So let's go back over to our EmployeeListItem and say EmployeeID and EmployeeName.
And of course, over in our EmployeeList now, we're going to need to change these over. So let's say EmployeeID and EmployeeName. OK.
So let's go over and give this a refresh. And there we go. So now you can see that we've got down from I think it was 18 or 17. We're down to 13 megabyte memory usage with a 374 millisecond request duration.
So we're still rendering out 1000 items, which is highly unlikely that you would do this. You would probably include some sort of pagination. So this is an extreme example, but still a pretty fast request duration and a massive improvement on what we had before.
It's pretty much been cut in half by just passing down the data that we need. So you can see that now over in Laravel DebugBar. We've got the EmployeeID and the EmployeeName. Now, let's just reduce this down a little bit.
So let's go over to our EmployeeList. And let's paginate this by let's just say 50. So still quite a few records in here. So we're getting a very, very short request duration and low memory usage
with these pieces of data in. Now, like I said before, the downside of if we come over to EmployeeList item, only passing through the data that we need is we might need more data in the future. So we might need to access something from here.
And it might get a little bit annoying to have to pass through lots of props. But that's fine, because what we can do is we can create some sort of getter to grab the employee by their ID if we need to perform any actions on them. Let's take a look at an example of that.
So let's just say that we had a button in here, which would delete an employee or edit an employee. And when we go ahead and click on that, we want to perform some sort of action. So for example, we just want to call DeleteEmployee.
And we'll implement this method over on EmployeeList item over in the LiveWire component. So let's create this method out, DeleteEmployee. And let's just die dump in here, just so we know that this is working.
Let's come over and let's click on Delete. There we go. So what we now want to do with this is look the employee up before we perform an action on them. So of course, we could very easily do that directly within DeleteEmployee.
So let's just die dump again on Employee, Find. And of course, we have the employee ID being passed in. So we can just find it like this. Let's make sure we pull in the namespace for the model.
And sure enough, when we click on that, we now have the employee model. So we can perform any actions on it, despite the fact we're not passing the entire employee object through. But this might get a little bit annoying having to look this up every single time.
We're going to cover computed properties later. But let's create our computed property for this employee, so we can access that employee when we need. So let's go ahead and just say, GetEmployeeProperty.
And let's return from here, Employee, and Find this employee ID. And now what we can do is die dump on this employee, kind of like what we would do if we were passing the entire object down. So this is going to have exactly the same result.
We're using that property, which is actually cached. And we're going to take a look at that a little bit later in exactly the same way. Now, you have to be really careful with this, because inside of each of your iterations, you're not going to want to call this,
because we are getting this every single time freshly for each employee ID. So this would be fine for something like deleting, because then we can just immediately access the model and call a delete method on it. But for example, inside of EmployeeListItem,
if you were using maybe some sort of method on the employee model, so let's open up employee.php and just create out some sort of getter, like full name or something like that. And we'll just return test here for now,
because I'm not actually doing anything with this. If you needed to access that inside of here, what you could do is say this employee, which will use that computed property, and then say full name.
But the problem with this is you're going to be executing a query for every single iteration. If we give this a refresh here, you can see that we've now got 53 database queries. So not a great idea for doing things like that. If you did want to use this full name thing, you could pass it down as another prop.
So let's just take a look at an example of that, and then we'll finish up. So if you did have a kind of getter over in your employee list, what you would then do is pass this down as a prop. So just think of every single piece of data that you need to access
inside of a LiveWire component as a prop. So let's say we had employee full name, which was using that method on the employee model. We could then just say employee and full name, like so.
So now over in our employee list item here, we would just accept that in as a prop. So employee and full name. And then you could just use that inside of your template. So if we just go over to the employee list item again, and we just say employee full name,
we now have the same data, but of course with less queries. So the computed property inside of employee list item is good for accessing this model when you need it, but not for every single iteration of that model.
But the speed improvement here is absolutely massive, down from what we saw before where we were passing that entire object in. And it's much better to pass in individual props rather than huge models where you're not going to need all of that data.
11 episodes1 hr 22 mins


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!


No comments, yet. Be the first to leave a comment.