List records very slow, creates a lot of models

Hi! We are currently working on performance improvement of our admin panel. Using the Laravel-debugbar library (https://github.com/barryvdh/laravel-debugbar) we found that for our database table with 56 users, 1130 User models are created when loading the User resource list page. Resulting in a load time of over 3 seconds with 45mb of memory usage. Is there any way to prevent or improve this?
GitHub
GitHub - barryvdh/laravel-debugbar: Debugbar for Laravel (Integrate...
Debugbar for Laravel (Integrates PHP Debug Bar). Contribute to barryvdh/laravel-debugbar development by creating an account on GitHub.
22 Replies
toeknee
toeknee2y ago
Ensure your filters where you have selects are closures, same with anything else that is possible to be iterated over.
Dennis Koch
Dennis Koch2y ago
Send some code for your table
TiBiBa
TiBiBaOP2y ago
I did already remove all filters, this reduces the models significantly and improved the performance from ~6 sec to ~3 sec.
return $table
->columns([
TextColumn::make('id')
->label('User ID')
->searchable(isIndividual: true, isGlobal: false),
TextColumn::make('username')
->searchable(isIndividual: true, isGlobal: false)->limit(20),
TextColumn::make('first_name')
->searchable(isIndividual: true, isGlobal: false)->limit(20),
TextColumn::make('sortable_last_name')
->label('Last name')
->searchable(isIndividual: true, isGlobal: false)->limit(20),
TextColumn::make('email')
->searchable(isIndividual: true, isGlobal: false)->limit(20),
TextColumn::make('school.name')
])
return $table
->columns([
TextColumn::make('id')
->label('User ID')
->searchable(isIndividual: true, isGlobal: false),
TextColumn::make('username')
->searchable(isIndividual: true, isGlobal: false)->limit(20),
TextColumn::make('first_name')
->searchable(isIndividual: true, isGlobal: false)->limit(20),
TextColumn::make('sortable_last_name')
->label('Last name')
->searchable(isIndividual: true, isGlobal: false)->limit(20),
TextColumn::make('email')
->searchable(isIndividual: true, isGlobal: false)->limit(20),
TextColumn::make('school.name')
])
Dennis Koch
Dennis Koch2y ago
You can probably improve performance by preloading the school relationship inside getTableQuery() on ListPage
TiBiBa
TiBiBaOP2y ago
Thanks! Do you have a code snippet example how to implement this?
Dennis Koch
Dennis Koch2y ago
But 3secs is still pretty slow. Also try php artisan icons:cache to cache the Blade Icons
TiBiBa
TiBiBaOP2y ago
We already cache the icons, this did not seem to improve the performance much. We're mostly wondering about the extensive amount of models, 1130 are created for only 56 users. It's unclear to us how this happens.
Dennis Koch
Dennis Koch2y ago
I think this should work on the ListPage:
protected function getTableQuery(): Builder
{
return parent::getTableQuery()->with('school');
}
protected function getTableQuery(): Builder
{
return parent::getTableQuery()->with('school');
}
Can you send a screenshot of the loaded models?
TiBiBa
TiBiBaOP2y ago
I don't have much information except the data from the debug bar:
Dennis Koch
Dennis Koch2y ago
Can you send a screenshot of the queries? 😅
TiBiBa
TiBiBaOP2y ago
Dennis Koch
Dennis Koch2y ago
What is line 142 in UserResource?
TiBiBa
TiBiBaOP2y ago
It's a custom action with a url: ->url(fn (User $user): string => $user->get('id'))
Dennis Koch
Dennis Koch2y ago
Why ->get()? This should be the way $user->id
TiBiBa
TiBiBaOP2y ago
Not sure, when using -> we get an error:
App\Admin\Resources\UserResource::App\Admin\Resources\{closure}(): Return value must be of type string, null returned
App\Admin\Resources\UserResource::App\Admin\Resources\{closure}(): Return value must be of type string, null returned
Dennis Koch
Dennis Koch2y ago
Ah, you renamed the param: ->url(fn (User $model) And $user->get('id') is equal to User::get('id') which loads the ids for every user.
TiBiBa
TiBiBaOP2y ago
Is the param name required to be $model? This results in the same error: ->url(fn (User $model): string => $model->id)
toeknee
toeknee2y ago
Are you just returning a list of users? I would adjust ->url() to be: ->url(fn( $record) => $record->id) I have a feeling your : string cast is the issue
Dennis Koch
Dennis Koch2y ago
Oh damn sorry. It's $record as Toeknee said. The param names must be the same as in the docs.
TiBiBa
TiBiBaOP2y ago
Thank you very much it's working! The loading time is still around 2 secs, but only 3 queries are created. Not sure what the bottleneck is at this point, but the querying is solved!
toeknee
toeknee2y ago
Great, it can be a few things. but I'd be ok with 2seconds for an crud app tbh.
Dan Harrin
Dan Harrin2y ago
if you disable the view collector in debugbar it usually speeds up also run artisan icons:cache
Want results from more Discord servers?
Add your server