Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Wakanda's avatar
Level 10

Is there a better way to do this query for performance?

Hi Devs,

I have a controller that returns products with images

controller

$this->products = Cache::remember('topSelling', now()->addMinutes(30), function() {
			return Product::inRandomOrder()->select(['name', 'slug', 'price', 'on_sale', 'is_new', 'id'])->with('photos:product_id,id,images')->take(8)->get();

and then in my view

@foreach($products as $p)
	{{ $p->name }}
	@if($p->photos->count() > 0)
                    <img class="lazy" 
                         src="{{ asset('frontend/img/image-loader.svg') }}"
                         data-src="/storage/{{ $p->photos->first()->images }} " 
                         alt=""
			>
          @else
                    <img src="{{ asset('frontend/img/no-image.png') }}" alt="">
          @endif
@endforeach

is there a way of optimizing the $p->photos->first()->images & @if($p->photos->count() > 0) query for performance

0 likes
6 replies
CorvS's avatar

First of all, you first use orderBy to order by created_at and then you use inRandomOrder. What exactly do you want? Additionally you could replace orderBy('created_at', 'DESC') with latest().

Since you only seem to use the first photo from each product, why eager load all photos using with?

Load only the first photo for each product:

@php($firstPhoto = $p->photos()->first())

@if($firstPhoto)
...
data-src="/storage/{{ $firstPhoto->images }}"
...
1 like
Snapey's avatar

what is images and why do you need first() on photos?

and, perhaps your random order could be applied to the foreach loop

1 like
Wakanda's avatar
Level 10

@snapey a product has many images and I need the first one to work as a thumbnail.

MichalOravec's avatar
Level 75

I would create a new relationship with default as well.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    public function photo()
    {
        return $this->hasOne(Photo::class)->withDefault([
            'images' => 'no-image.png'
        ]);
    }

    public function photos()
    {
        return $this->hasMany(Photo::class);
    }
}
1 like

Please or to participate in this conversation.