dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.18k stars 9.93k forks source link

Enable `debounce` / `throttling` for events #10522

Open mkArtakMSFT opened 5 years ago

mkArtakMSFT commented 5 years ago

This will allow the user to register for scroll events with some time period (100ms) which will filter out events happening within the period, and result in much fewer events being sent to the server.

arivoir commented 5 years ago

Apart from having a delay, the events should be automatically dispatched, and filtered, depending on the real time the event is taking to be processed in the server(notice the network latency and the time involved in process the request counts).

Something like this

@functions
{
    object currentEventValue;
    System.Threading.SemaphoreSlim semaphore;

    private async void OnNativeEvent(string value)
    {
        try
        {
            currentEventValue = value;
            await Task.Delay(100);
            await semaphore.WaitAsync();
            if (currentEventValue == value)
            {
                await CallEventAsync();
            }
        }
        finally
        {
            semaphore.Release();
        }
    }
}
Andrzej-W commented 5 years ago

I asked for this about year ago. Unfortunately the issue was closed with suggestion that I can do it using some JavaScript code. If it will be implemented it should be possible to use throttling and debouncing in all events. Think about resize events, dragging, or input events when you want to implement incremental search and you don't want to query database after each keystroke.

ctrl-alt-d commented 5 years ago

Maybe you can use a Timer as workaround.

ghost commented 3 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

braidenstiller commented 3 years ago

Not sure if this issue is also scoped for WASM, but this feature would be useful there as well.

In high-performance events like dragging I am noticing the ondrag event absolutely smash do_runtime_invoke during periods of significant mouse movement. This results in significant delays in the events being called and in turn, a lagging UI experience.

image

image

The workaround for the time being is to manually handle the drag event in JS and throttle it's calls to DotNet there, but it would be nice to have this supported natively.

braidenstiller commented 3 years ago

Any update on this one?

An idiomatic way to debounce and/or throttle events in the Blazor syntax would be really useful. Adding a way to flag for passive events would also be beneficial for high performing on scroll events.

<div @ondrag="Foo"
     @ondrag:throttle
     @ondrag:throttle-interval="500"
     @ondrag:passive>
</div>

<div @oninput="Bar"
     @oninput:debounce
     @oninput:debounce-interval="500">
</div>

I implemented a custom solution using components and JS interop but without a way to create directives in razor syntax it's quite clunky.

Any native solution I'd also expect to throttle/debounce in JS rather than in the wasm runtime as the majority of the perf penalty seems to come from js slamming the runtime invoke as mentioned above.

TanayParikh commented 2 years ago

Found this community project which provides some debouncing functionality: https://blazorextensions.z6.web.core.windows.net/debounceinput

ghost commented 1 year ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

ghost commented 8 months ago

Thanks for contacting us.

We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

ericgrantholland commented 5 months ago

I think this is a necessary feature to work with many of the events already exposed on Blazor side, especially for ServerSide Blazor. Really don't want OnMouseOver event firing a million times sending Signal R messages at that rate. I know there is a way around this with custom JS but it's a huge hassle. Need to write both JSSetup and JSCleanup for every event you want to handle.

Would be really cool if you could set the interval directly from razor syntax, similar to how stopPropagation and preventDefault work now. See below:

<div @onmouseover="@OnMouseOver" @onmouseover:throttle="160" >
This div mouse over event throttles 160ms
</div>

<div @onmouseover="@OnMouseOver" @onmouseover:debounce="500" >
This div mouse over event debounces 500ms
</div>

Without this level of control, many already exposed events aren't useful in blazor. Fire too often and cause problems.