DominikDoom / a1111-sd-webui-tagcomplete

Booru style tag autocompletion for AUTOMATIC1111's Stable Diffusion web UI
MIT License
2.55k stars 306 forks source link

Characters getting swallowed while typing #40

Closed byzod closed 1 year ago

byzod commented 1 year ago

When showAllResults is true (as I said in https://github.com/DominikDoom/a1111-sd-webui-tagcomplete/issues/34#issue-1420740828, it's basically necessary for chinese users), characters maybe swallowed when typing, even with small resultStepLength (50 in my case)

Demo: when I try to type guro An2

A possible and popular way to solve this is to delayed the keypress event handler until user stop typing, or handle it asynchronously

For example generate the dropdown list keypressHandlerDelay ms later after user stops typing, the default value of the delay could be 300 ms or something and can be changed in config.json

DominikDoom commented 1 year ago

Swallowing characters has never happened to me before, even when resultStepLength is a much higher value like 50000. Yes, the browser will lag for potentially seconds in that case - but the typed characters are still queued and will still be input after it catches up:

https://user-images.githubusercontent.com/34448969/197771776-f1f8b06a-99ed-40f7-af0b-920ccc11a9de.mp4

In this clip I typed them all at the beginning, and it will obviously lag since it tries to display 50000 entries at first, but still adds the rest of the characters afterwards.

Also regarding your delay suggestion, in fact this is already in place: the key change listener uses a debounce function which prevents re-triggering the function until the timer has passed. Default value is 100 ms. Since I can't seem to reproduce the character swallowing, please try out the following:

This should be line 675 of tagAutocomplete.js, try editing the 100 to a higher value, like 300, 500 or even 1000.

area.addEventListener('input', debounce(() => autocomplete(area, area.value), 100));

If it helps your situation to have a higher timer, I can add that to the config.

A proper asynchronous implementation would be the only proper solution to the core problem, but with smaller step sizes I never felt the need, at least on my system. What are your specs?

byzod commented 1 year ago

A proper asynchronous implementation would be the only proper solution to the core problem, but with smaller step sizes I never felt the need, at least on my system. What are your specs?

Thanks, bad news: increase 100 to 1000 not working

Good news: I found out a different behavior

I wrote a GM script and ahk script found out that it's not your script but both firefox+your script swallowed the keypress 2

The keypress are NOT swallowed on Microsoft Edge and Chrome, only on Firefox and I can reproduce it on a fresh new profile so it's not a extension related bug, can you investigate it?

p.s. I never had similar problem on firefox with other scripts or web applications so I think my firefox is not broken, maybe

Firefox I use: https://ftp.mozilla.org/pub/devedition/candidates/107.0b4-candidates/build1/win64/zh-CN/firefox-107.0b4.zip

Webui config and test script (if it helps): config.zip

Spec and webui command args

OS Name : Windows 10 Home China (64-bit) 
OS Version : 21H2
OS Build : 19044.2130
Current ANSI codepage : 936
COMMANDLINE_ARGS=--xformers --no-half-vae --deepdanbooru
DominikDoom commented 1 year ago

Alright, thanks for the details. I'll try it on Firefox and see if I can find the cause.

DominikDoom commented 1 year ago

Very strange, even using the Firefox version and the test scripts you gave me, I can't reproduce the swallowing bug. It behaves pretty much the same as my Chrome instance in that regard. I tried various settings but none made a difference for it.

Does it also happen at smaller step sizes? 50 items shouldn't cause much lag.

byzod commented 1 year ago

Very strange, even using the Firefox version and the test scripts you gave me, I can't reproduce the swallowing bug. It behaves pretty much the same as my Chrome instance in that regard. I tried various settings but none made a difference for it.

Does it also happen at smaller step sizes? 50 items shouldn't cause much lag.

It happens even with 20 step size ;_;

With 20 steps it's not lag that much, but I still lost some input

I can't think of what could cause this problem :/

DominikDoom commented 1 year ago

What CPU & RAM do you have, if that isn't too private? At 20 I am really surprised to hear you still have noticeable lag.

byzod commented 1 year ago

Also regarding your delay suggestion, in fact this is already in place: the key change listener uses a debounce function which prevents re-triggering the function until the timer has passed. Default value is 100 ms. Since I can't seem to reproduce the character swallowing, please try out the following:

This should be line 675 of tagAutocomplete.js, try editing the 100 to a higher value, like 300, 500 or even 1000.

area.addEventListener('input', debounce(() => autocomplete(area, area.value), 100));

I set this value to 2000 and it won't swallow my input before the dropdown list shown, thanks!

I will use this as a workaround for now

What CPU & RAM do you have, if that isn't too private? At 20 I am really surprised to hear you still have noticeable lag.

i5-11400F & 16GB RAM & RTX 3060Ti

It's not a super pc but I think it can handle few js script...

To be clear that when using low step size, it's not lag, just input got swallowed, the dropdown list generated almost instantly

Demo: me trying to type goggles with step size 100, the result shows up quick but words swallowed An1

DominikDoom commented 1 year ago

i5-11400F & 16GB RAM & RTX 3060Ti

Yeah with that it should definitely be no problem.

If the swallowing isn't related to lag it's even stranger. The script shouldn't prevent key events at any time, and only blocks the default for the navigation keys like Arrow Up/Down etc. If the workaround with the high debounce works in the meantime that's good, I'll get back to you if I find anything else.

Evil-Dragon commented 1 year ago

I opened a bug report that is the same issue to this, when typing something into the boxes it would miss letters and spaces. I thought i'd broken my keyboard. Didn't think at the time that this bug report was related but it is. I was using the default "resultStepLength": 500, but never changed it, i suspect it woud happen no matter what step length I choose.

EDIT: I'm using English so i doubt this is specifically related to Chinese.

DominikDoom commented 1 year ago

@Evil-Dragon Can you try launching your Firefox in safe mode (Hold shift wile starting it)? I'm still looking for what could cause this since it works normally on my Firefox with Win10.

Evil-Dragon commented 1 year ago

firefox_CicPKDmc79

This is in Firefox Safe Mode. I was typing 1girl, sitting at a park bench.

I really wish I could say that my typing is that bad but it isn't, lol

EDIT: Gonna try some of your script roll backs and see when it started happening.

DominikDoom commented 1 year ago

That confirms it doesn't have anything to do with extensions, settings, etc. which matches what byzod reported.

EDIT: Gonna try some of your script roll backs and see when it started happening.

That would be great, if doesn't occur in prior versions I'll at least have a starting point.

Evil-Dragon commented 1 year ago

Hotfix 1.7.1 was stable for me, no missed characters or spaces when typing. I didn't try 1.7.2 because that was causing some infinite wildcard reloading of 30+ text files and it was killing my Firefox at the time. Obviously 1.7.3 was released to address that issue but it seems it might have caused some additional issues or it started in 1.7.2, not too sure.

DominikDoom commented 1 year ago

Could you try 1.7.2 with wildcards disabled and see if the characters are swallowed there? 1.7.3 didn't change anything regarding normal completion, so I don't think it's that.

byzod commented 1 year ago

I tried 1.7.1, still got swallowed, I think we have different issue ;_;

DominikDoom commented 1 year ago

Might also just be a misremembered version then.

Since I can't really do testing without the cause, can you please try to comment out line 475 (in the newest version)?

addResultsToList(textArea, results, tagword, true);

That way the autocomplete function still gets called, but the results aren't added to the div. I want to find out if it's related to the displaying or processing.

Evil-Dragon commented 1 year ago

1.7.2 seems ok with wildcards disabled. Not getting any swallowed characters.

Evil-Dragon commented 1 year ago

And now it appears 1.7.3 is working without issue, i'm totally lost. Caching issue? I've been making a habit of disabling cache in F12 between upgrading and testing these latest versions. Perhaps something was getting cached causing the typing dropouts? That said right now I have wildcards and embedding and translation as set as false.

byzod commented 1 year ago

And now it appears 1.7.3 is working without issue, i'm totally lost. Caching issue? I've been making a habit of disabling cache in F12 between upgrading and testing these latest versions. Perhaps something was getting cached causing the typing dropouts? That said right now I have wildcards and embedding and translation as set as false.

Even ctrl+f5 is not enough to reload it correctly, I always close webui and reboot it to make sure no cache is messing with

DominikDoom commented 1 year ago

Even ctrl+f5 is not enough to reload it correctly, I always close webui and reboot it to make sure no cache is messing with

Yeah for the script itself you need to restart the webui, but that's due to gradio preprocessing the website. So the new version of the script only gets processed & added to the server at startup, not during normal page reloads.

But either way caching shouldn't cause the missing characters.

byzod commented 1 year ago

Might also just be a misremembered version then.

Since I can't really do testing without the cause, can you please try to comment out line 475 (in the newest version)?

addResultsToList(textArea, results, tagword, true);

That way the autocomplete function still gets called, but the results aren't added to the div. I want to find out if it's related to the displaying or processing.

Finally something different

I change line 475 to two lines

 // addResultsToList(textArea, results, tagword, true);
 console.log("try to add results");

Then in the prompt area, typing feels smooth like hell, not a single character got swallowed and there are many log in console so it's actually working

I suppose this means it's a render issue?

DominikDoom commented 1 year ago

Seems like it, addResultsToList is where the list elements are created and added to the autocomplete popup div. So it seems very likely to me that Firefox misses the input because the DOM gets manipulated or a re-render is triggered during that time.

Please try this version of the script: tagAutocomplete.zip

I tried making the whole autocomplete function async, but don't know if it had an effect.

byzod commented 1 year ago

Seems like it, addResultsToList is where the list elements are created and added to the autocomplete popup div. So it seems very likely to me that Firefox misses the input because the DOM gets manipulated or a re-render is triggered during that time.

Please try this version of the script: tagAutocomplete.zip

I tried making the whole autocomplete function async, but don't know if it had an effect.

The delay 2000 is too long to feel any difference so I change it to current default 100

Still a lot of input got swallowed :/

DominikDoom commented 1 year ago

Ah yeah that was left high from testing since you previously said the high delay fixed it for you, sorry.

With 2000 it feels really slow to use though, so I would like to find the real problem. Might also be related to this bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1098981 Although that is for machine typing without delay. But changing the results list here might aggravate it enough so that it even happens for user typing.

Just out of interest, what happens if you set the delay to 0? Does it get worse or stay the same?

byzod commented 1 year ago

Ah yeah that was left high from testing since you previously said the high delay fixed it for you, sorry.

With 2000 it feels really slow to use though, so I would like to find the real problem. Might also be related to this bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1098981 Although that is for machine typing without delay. But changing the results list here might aggravate it enough so that it even happens for user typing.

Just out of interest, what happens if you set the delay to 0? Does it get worse or stay the same?

I thought I would lag like shit but it actually fix the problem..sort of..?! 🤔 An1 Few characters still got swallowed if I type at hyper speed, but at my normal speed it works at a decent level, it's working for me at this kind of usability

I tested 3 version of line 675, all of them feels almost the same (the synchronous version feels a bit of laggy but not sure if it's just my feelings)

        area.addEventListener('input', debounce(async () => await autocomplete(area, area.value), 0));

        area.addEventListener('input', async ()=>await autocomplete(area, area.value));

        area.addEventListener('input', ()=>autocomplete(area, area.value));

I still don't know what caused the problem but now I got a good acceptable workaround, thank you for all the effort :D

p.s. I tested with the version you provided, didn't tested the released version

DominikDoom commented 1 year ago

p.s. I tested with the version you provided, didn't tested the released version

That shouldn't make much of a difference, in the custom version I only added the async/await keywords. So if no delay helped, it should have the same effect with the live version. But if you want, try it with the live version too to make sure.

I'll add the debounce delay as a config option so that it doesn't get overwritten in updates.

byzod commented 1 year ago

40d53d89d16c6fd6e4e05d9ad8f9a46ac27c1352 working confirmed, by setting the debounce delay to 0 https://github.com/DominikDoom/a1111-sd-webui-tagcomplete/blob/40d53d89d16c6fd6e4e05d9ad8f9a46ac27c1352/javascript/tagAutocomplete.js#L675

DominikDoom commented 1 year ago

I've added the config option, default is still 100, so you will have to edit the config and set it to 0 there.

I'll keep this issue open since it's not solving the actual problem though.

DickJokez69 commented 1 year ago

I haven't tried any of the newer versions, but I also had issues with the autocomplete eating left/right inputs from the arrow keys when the list shows up, making it hard to move the text cursor around if you've made a mistake. up/down I totally understand, but not left/right, since they're not used to navigate that list afaik.

DominikDoom commented 1 year ago

@DickJokez69 Left and right arrows were used to jump to the first/last result of the list in the past, but that has been turned off by default for a few versions since I added Home/End as a less intrusive alternative.

thojmr commented 1 year ago

Wanted to chime in and mentioned I have been having the same issue, and that setting delayTime to 0 does not fix it.

Firefox, windows 10, WSL, plenty of CPU and RAM available

DominikDoom commented 1 year ago

This is such a strange bug, I'm especially confused why I can't reproduce it on my Firefox no matter what I try. It can't be related to typing speed since I couldn't even reproduce it using the AHK script, it can't be settings, cache, or browser extensions since it also happens on safe mode and fresh profiles, it can't be version related since I also tried with the specific build @byzod provided. Hardware seems unlikely too since it also happens with software input in the script and we all have enough specs to run a bit of js. OS also is Win10 for all of us. Language specific problems are also out since it happened in Chinese and English but not for me when I tried it in those two and my own. Delaying the autocompletion seems to have no logical influence on whether it gets better or worse contrary to what I would expect.

At this point I can't really think of anything else that differentiates my setup from others. And yet no matter the delay or speed I've never seen a single letter missed that I didn't mistype myself. This is some haunted PC creepypasta level of illogical.

thojmr commented 1 year ago

If it helps, it only occurs when images are being generated, and potentially only when a step is started/ending. Is there any process in your code that is being run on every step of the diffusion? Earlier I remember seeing an error log on every step from your script, but I forgot what caused it to begin with. No error messages in either browser or terminal now though.

byzod commented 1 year ago

If it helps, it only occurs when images are being generated, and potentially only when a step is started/ending. Is there any process in your code that is being run on every step of the diffusion? Earlier I remember seeing an error log on every step from your script, but I forgot what caused it to begin with. No error messages in either browser or terminal now though.

I barely encounter any swallowing when set delay to 0, but still got many swallowed when image generating. Maybe it is related to performance after all, js/css engine or something

DominikDoom commented 1 year ago

Is there any process in your code that is being run on every step of the diffusion

Not really. I use just the input change listener of the promt textboxes to trigger the autocomplete. There is a part that is triggered by Gradio's onUiUpdate function and would run on every step, but that is only for one-time setup after Gradio finished loading and exits out early on every other call. So logically it shouldn't influence performance.

But I'll definitely try if characters are getting missed for me while generating on Firefox, might be a lead if I can reproduce it.

DominikDoom commented 1 year ago

But I'll definitely try if characters are getting missed for me while generating on Firefox, might be a lead if I can reproduce it.

Still no luck, no letters swallowed for me while generating.

I changed the setup code to a one-time call instead of exiting early out of onUIUpdate, so now there should be no code at all running without user input after that one time setup. Doubt it changes anything for this issue but worth a try (and it's cleaner code anyway).

thojmr commented 1 year ago

I think that change fixed the issue for me. Just grabbed the latest and I have not lost a single character since.

DominikDoom commented 1 year ago

I'm closing this issue for now since it's been inactive for a while and I haven't gotten new reports in the meantime, but if the problem still exists for one of you, feel free to reopen.