-
-
Notifications
You must be signed in to change notification settings - Fork 677
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
cancel_on_exit cancels hidden elements even when loadAll() is called #469
Comments
Hi again @starfishpatkhoo , I've tried to reproduce the bug you're reporting on the following demo, but I couldn't reproduce the bug. The instance of LazyLoad is public under the global variable Cases I've tested: Calling the Calling the Would you be able to double check it? |
@starfishpatkhoo any feedback would be appreciated |
OK, so I wanted to send you a codepen, but.. I could nor reproduce the error either. I went back to my original code, and the problem wasn't there! I thought I was going crazy or something.. LOL! The problem is therefore intermittent, and comes and goes (my F5 key is worn out now :) But after a lot of trial and error, I think I have managed to narrow it down. Essentially, it is a race condition. No Error: Have Error: The two screenshots above are on the same site, with no code changes in between, just trying and pressing F5 many times. Usually, on the second or third try, the error will show up. What happens is that loadAll() starts loading the image, but while it is still loading, IO triggers, but this is a hidden div, so IO says it is "exit-ed" and triggers cancel_on_exit(). Which of course, cancels it (because loading has not completed yet). This is quite difficult to reproduce, since it has to happen in exactly the right timing. In my case, I fire loadAll() via a setTimeout() on document.ready(), but I guess as a race condition, it could happen in some other "coincidental" situation. I suspect this will be more obvious on a slow or overloaded browser/PC. Maybe with many extensions/tabs/JS/VMs active for example. With that in mind, the fix I tried out is this, on --- src/lazyload.js 2020-06-25 13:43:34.000000000 +0800
+++ src/lazyload.NEW.js 2020-06-29 14:27:19.514757500 +0800
@@ -56,6 +56,7 @@
const settings = this._settings;
const elementsToLoad = getElementsToLoad(elements, settings);
elementsToLoad.forEach((element) => {
+ unobserve(element, this);
load(element, settings, this);
});
} As you can see, normally when the element has been loaded, it will be unobserved. Since we are doing a force load, we stop observing it before attempting to load the element. Seems OK so far, after a few reloads. Again, this is just my rough understanding of the problem. I am not too sure of the correct/proper way to fix this race condition. Possibly there are other problems that will arise that I'm not aware of. :/ |
Hey @starfishpatkhoo , I think the solution you're proposing makes lots of sense and I can't think of a better one. Let me just point out that calling |
I tried to put some hidden images in the load_all.html demo, but I wasn't able to reproduce the bug in any case. Also, a couple of versions ago this script was doing exacly that: unobserve when start loading. I decided to leave the element observed until it finished loading only a couple of versions ago to implement the |
Hey @starfishpatkhoo , You might want to double check that everything is fine on your side. After that, If you’re happy with my support, the documentation and the effort I’ve been putting on this project in the latest years, I hope you might want to buy me a coffee to show your appreciation. Open-source software is great for everyone, but it takes passion and time to grow and evolve. Thank you for thinking about it. |
Hi @verlok, 17.1.0 works well so far! I will keep using it and monitoring, since it is a race condition. But so far, I haven't seen it fail yet. Nice one! I think you did the right thing by keeping it observed for cancel_on_exit(). But yes, loadAll() is probably a special case. Heck, I think my whole usage is a special case anyway. I rely on some JS events to do some image stuff, but browser support is not very stable at the moment. As a result, I ended up using what I call a "deferred" loading approach together with "eager", "lazy". Basically, it is simply "eager", but delayed for a certain amount of time until after document.ready(). The main page and everything else works as per normal, eager is eager, everything else is lazy. But for these special images, I load it say 7000ms after the rest of the document is done. Anyway, like I said, this is a very uncommon use case. And probably I won't need "deferred" once browser support is rock solid. But right now, sad to say, have to use some UA sniffing. Sniff. Sniff. Thank you again, excellent stuff! :) |
Hey @starfishpatkho, If you’re happy with my support, the documentation and the effort I’ve been putting on this project in the latest years, I hope you might want to buy me a coffee to show your appreciation. Thank you for thinking about it. |
I'm not sure if this is a bug or simply by design. If so, perhaps documentation can be updated. :)
In 16.1, it would load, but in 17.0 the image loading would be cancelled because the div is hidden (I guess?). If you add
cancel_on_exit: false
as an option then the image is loaded just fine.Not sure if that's how I had intepreted loadAll() which I assumed was to force loading of all images regardless of visibility.
Version: 17.0
Browser: Chrome 83
The text was updated successfully, but these errors were encountered: