filamentphp / filament

A collection of beautiful full-stack components for Laravel. The perfect starting point for your next app. Using Livewire, Alpine.js and Tailwind CSS.
https://filamentphp.com
MIT License
18.66k stars 2.9k forks source link

UI feels sluggish on high latency connections because of fixed `wire:loading.delay` #8408

Closed binaryfire closed 1 year ago

binaryfire commented 1 year ago

Package

filament/filament

Package Version

3.0.46

Laravel Version

10.2.6

Livewire Version

3.0.1

PHP Version

8.2

Problem description

@danharrin First of all, thanks for your hard work on v3!

The default value of wire:loading.delay is 200ms which is ok for users close to the server, since most requests complete before that. However users on the other side of the globe have an additional 300-400ms latency on top of each request. We're in Australia and are developing a resource-intensive app which needs dedicated servers. The only affordable ones are in the US / Europe which means we have to factor that latency into how we build our UIs. Have a look at the ping times from Sydney and you'll see what I mean.

The result is that we get loading indicators for every request Filament makes (which is great) but they don't appear for 200ms (not so great). It makes the whole app feel very sluggish. Our current VueJS dashboard feels snappy by comparison because it displays indicators immediately (even though it takes about the same amount of time to return data).

Expected behavior

It'd be great if we could configure this behavior in config/filament.php. Livewire has multiple values for delays. So maybe:

And then do something like this to make it reusable?

    public function getWireLoadingDelayAttribute(): string
    {
        if (config('filament.wire_loading_delay_disable')) {
            return '';
        }

        $delayValue = config('filament.wire_loading_delay', '');
        return empty($delayValue) ? 'wire:loading.delay' : 'wire:loading.delay.' . $delayValue;
    }

Steps to reproduce

If testing from US or the UK, just launch any Filament app on a VPS in Australia then click around.

Reproduction repository

https://github.com

Relevant log output

No response

github-actions[bot] commented 1 year ago

Hey @binaryfire! We're sorry to hear that you've hit this issue. 💛

However, it looks like you forgot to fill in the reproduction repository URL. Can you edit your original post and then we'll look at your issue?

We need a public GitHub repository which contains a Laravel app with the minimal amount of Filament code to reproduce the problem. Please do not link to your actual project, what we need instead is a minimal reproduction in a fresh project without any unnecessary code. This means it doesn't matter if your real project is private / confidential, since we want a link to a separate, isolated reproduction. That would allow us to download it and review your bug much easier, so it can be fixed quicker. Please make sure to include a database seeder with everything we need to set the app up quickly.

binaryfire commented 1 year ago

@danharrin Working on a PR for this. What do you think about using an Enum?

<?php

namespace Filament\Support\Enums;

enum WireLoadingDelay: string
{
    case none = 'wire:loading';
    case shortest = 'wire:loading.delay.shortest';
    case shorter = 'wire:loading.delay.shorter';
    case short = 'wire:loading.delay.short';
    case default = 'wire:loading.delay';
    case long = 'wire:loading.delay.long';
    case longer = 'wire:loading.delay.longer';
    case longest = 'wire:loading.delay.longest';

    public static function getAttribute(): string
    {
        return match(config('filament.wire_loading_delay')) {
            'none' => self::none->value,
            'shortest' => self::shortest->value,
            'shorter' => self::shorter->value,
            'short' => self::short->value,
            'long' => self::long->value,
            'longer' => self::longer->value,
            'longest' => self::longest->value,
            default => self::default->value,
        };
    }
}

That'd allow the correct string to be used in Blade templates like this:

@php
    $wireLoadingDelay = \Filament\Support\Enums\WireLoadingDelay::getAttribute();
@endphp

{{ $wireLoadingDelay }}

or

@php
    use Filament\Support\Enums\WireLoadingDelay;
@endphp

{{ WireLoadingDelay::getAttribute() }}