Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typing too quickly undone by response #100

Closed
grantjenks opened this issue Dec 21, 2020 · 9 comments
Closed

Typing too quickly undone by response #100

grantjenks opened this issue Dec 21, 2020 · 9 comments
Assignees

Comments

@grantjenks
Copy link

Love where this project is headed! I came here from Flask-Meld which also seems to be running with the idea.

Small UX issue I noticed on the search auto-complete demo for state names. If I type really quickly on my phone the input changes and undoes my typing.

Haven’t looked yet in a debugger but my hypothesis is that typing quickly fires a request for each keystroke. Some of the responses then return after I’ve typed more characters. Since the DOM is being used for internal state, the old state gets echoed back by the first few requests and stomps on the new state.

Not sure what the best fix is. Maybe the responses should be discarded unless it corresponds to the latest request? That seems right for input elements but maybe not for others.

@adamghill
Copy link
Owner

Hey @grantjenks! Yeah, it's a challenging problem to have a good default. I have experimented with multiple different queuing and debouncing techniques over time, but currently I debounce with a 250ms delay (by default):

debounce(send, 250, false)(this, callback);
.

There are also a few different ways to change how often an input sends data to the backend component (defer, lazy, debounce): https://www.django-unicorn.com/documentation/components/templates#modifiers.

However, I think Laravel Livewire uses a JS event bus which might be a better approach to handle really fast input changes, so it might be something I look into in the future.

I'd love if you have any insight into how to make the situation better!

@krims0n32
Copy link

Have you thought about using websockets instead of async requests? That way you can make sure the input and output always go out and in sequentially.

@adamghill
Copy link
Owner

I've thought about it, but IMO one of the benefits of sticking to AJAX requests is to reduce the initial setup (no redis pub/sub or other broker required, no Django channels setup, etc). I also don't have to deal with websockets that disconnect, etc. Keeping everything simple (deployment, server ops, conceptually, etc) is a key goal of Unicorn.

However, I do have websockets support as a potential option for the future.

@zeroepix
Copy link

zeroepix commented Jan 5, 2021

This will be less of an issue if you're close to the hosting server, but it's quite a disjointing experience if you're far away (like I probably am). Could you prevent it from writing to the input field on return?

@adamghill
Copy link
Owner

Could you prevent it from writing to the input field on return?

This is a really good point and actually what I used to do. In 61d56cb I removed skipping updating the field that triggered a model update because there were some edge cases where it would lead to incorrect behavior. I'm going to look into this again and see if I can make it work, though.

adamghill added a commit that referenced this issue Jan 5, 2021
… to handle the edge where a model and action are on the same element and fire at the same time. #100
@adamghill
Copy link
Owner

I think I have at least a good start in #109. I've been testing locally in Firefox with the network throttle set to "Regular 2G" to simulate a slower network speed and the input updates aren't nearly as choppy.

I have 2 major test cases right now.

Type rapidly into something like this and make sure it looks smooth:

 <input type="text" u:model="state" placeholder="State name" id="typeahead2"></input>

Make sure that typing in this sets the field as expected.

<input type="text" u:model="state" placeholder="State name" id="typeahead3" u:keyup="state='hello'"></input>

I need to test all of the edge cases some more, but I'll release it as 0.14.1 if it looks good as soon as I'm able.

@adamghill adamghill self-assigned this Jan 5, 2021
@adamghill
Copy link
Owner

#109 got merged into master and I released these fixes as part of 0.14.1. I think that should clear up this issue so I'm going to close it, but feel free to open a new issue if you still see problems after updating to 0.14.1.

@krims0n32
Copy link

Thanks for fixing this. A similar issue is present in the "Click counter" example (https://www.django-unicorn.com/examples/click-counter), but that might be more difficult to fix?

@adamghill
Copy link
Owner

A similar issue is present in the "Click counter" example..., but that might be more difficult to fix?

Yeah, it's a little trickier because actions need to go through the AJAX endpoint to make sure that the correct data is returned. I created two new issues: #111 to look into approaches for actions in general, and #110 as a more deep-dive performance optimization issue to make sure that all parts of the lifecycle is as fast as possible.

will9288 added a commit to will9288/django-unicorn that referenced this issue May 6, 2024
… to handle the edge where a model and action are on the same element and fire at the same time. adamghill/django-unicorn#100
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants