filament icon indicating copy to clipboard operation
filament copied to clipboard

Navigation Loaded Twice, Causing Badge SQL Query to Run Twice

Open PovilasKorop opened this issue 1 year ago • 6 comments

Package

filament/filament

Package Version

v3.2

Laravel Version

v11

Livewire Version

No response

PHP Version

8.2

Problem description

While preparing a video based on the official filament demo, noticed two queries running for the badge:

Screenshot 2024-06-25 at 09 25 44

Debugged a bit deeper and discovered that the whole menu is being loaded twice.

Confirmed that I'm not alone, by two discussions opened by the same person:

  • https://github.com/filamentphp/filament/discussions/10285
  • https://github.com/filamentphp/filament/discussions/10204

But those discussions didn't lead to any issues opened, at least I haven't found, so creating one.


Made a bit of a source-dive. Managed to locate the problem but didn't manage to fix it.

Discovered that new NavigationManager() is called twice: https://github.com/search?q=repo%3Afilamentphp%2Ffilament%20new%20NavigationManager&type=code

  • In FilamentServiceProvider
  • And in HasRoutes concern

There seems to be a check to prevent double-loading but for some reason it doesn't trigger for me: https://github.com/filamentphp/filament/blob/d00919cbac22c9b8648b114815ab635aaac6d509/packages/panels/src/Navigation/NavigationManager.php#L49

if (! $this->isNavigationMounted) {
    $this->mountNavigation();
}

P.S. Interesting part: during my testing, seems that the Cluster part of the menu (Products + Categories + Brands) is loaded only once, not twice. So there's some separate different logic for clusters, probably.

Expected behavior

There should be one SQL query: either by not duplicating the query, or not duplicating the navigation manager call.

Steps to reproduce

Just load the official demo locally and load any page with Laravel Debugbar and see the queries

Reproduction repository (issue will be closed if this is not valid)

https://github.com/filamentphp/demo

Relevant log output

No response

PovilasKorop avatar Jun 25 '24 06:06 PovilasKorop

It looks like this issue was introduced by @danharrin as part of #11292 (Boost Octane performance further) in a47673bc44a57cfc115bc7067164dfaf9f329c90 and modified further in 12cc2730b7a545240eba3c2b9e629743cbb513cb, where it was intentionally switched from loading from the service container to newing up a fresh NavigationManager.

rossbearman avatar Jul 02 '24 09:07 rossbearman

A fast workaround for big tables that slowing down the display of the table is to use Cache, until the final fix, e.x.

$newMails = Cache::remember('filamentMailsBandge', now()->addSeconds(30), function () {
    return static::getModel()::where('created_at', '>=', Carbon::now()->subHours(12)->toDateTimeString())->count();
});

sdiama avatar Aug 06 '24 08:08 sdiama

What about use once() helper to cache the callback to memory.

https://laravel.com/docs/11.x/releases#the-once-function

    public static function getNavigationBadge(): ?string
    {
        return once(function () {
            return number_format(static::getModel()::count());
        });
    }

tommy66374 avatar Feb 09 '25 20:02 tommy66374

Not sure if this should be dropped here, but the getNavigationBadge method is also executed for all tenants that the user is connected to, instead of only the active tenant.

Image

emielroelofsen avatar Mar 10 '25 13:03 emielroelofsen

I’m experiencing the same issue with badge on tabs in Filament Tables.

collect(Status::cases())->mapWithKeys(function (Status $status) {
            return [
                $status->value => Tab::make($status->getLabel())
                        ->badge(function () use ($status) {
                            return Product::where('status', $status)->count();
                        })
                        ->modifyQueryUsing(function (Builder $query) use ($status) {
                            $query->where('status', $status);
                        }),
            ];
        });
Image

SupianIDz avatar May 27 '25 14:05 SupianIDz

The problem is now increased with v4.0.0-beta with 3 duplicate queries not only 2. which means that the method is loaded 3 times

Image

ht3aa avatar Jun 10 '25 13:06 ht3aa

Fixed in v4 by #16624

danharrin avatar Jun 21 '25 15:06 danharrin