Most user-facing performance issues come from inefficient use of the database. One of the most common (and easiest solved!) problems is the dreaded "N+1 problem". If you loop over an Eloquent collection and access a relationship, but forgot to eager-load that relationship: you've just caused an N+1 problem.
Telescope surfaces these scenarios when you drill in to the Queries tab. Notice how it says I ran 17 queries in this request, but 6 are duplicated. That is an N+1 problem.
Sometimes, though, you have an N+1 issue, and it doesn't feel slow. In the example request above, the total database time was 7.05ms, and that's including the N+1 issue. You're not going to notice that as slow until you encounter a scenario where there are a lot more related records.
You could review every request in Telescope to look for this, but there's a more convenient way to find all N+1 issues, whether they're perceptible or not. Laravel offers lazy loading protection. With this setting enabled, any N+1 issue will throw an exception, so it can't be ignored. It's simple to set up, just add this one line to the boot()
method in your AppServiceProvider
.
use Illuminate\Database\Eloquent\Model;
/**
* Inside your AppServiceProvider
*/
public function boot(): void
{
Model::preventLazyLoading(! $this->app->isProduction());
}
Notice the environment check. You really do not want to turn this on in production. It's great to catch it when using the UI locally, or when running your full test suite, but you don't want to interrupt a real user in production for a performance issue.
Here to help,
Joel
P.S. Validation is really important in your app, but it doesn't always get the attention it deserves. We've written the ultimate guide to Laravel validation rules to help you get the most out of this powerful feature.