tvler / lazy-progressive-enhancement

A lazy image loader designed to enforce progressive enhancement and valid HTML.
http://tylerdeitz.co/lazy-progressive-enhancement/
MIT License
190 stars 10 forks source link

Are multiple intervals created? #9

Open simevidas opened 8 years ago

simevidas commented 8 years ago

If I’ve read the code correctly, multiple setInterval timers are created (one per image). Could this be optimized? I’m not sure if this is a micro-optimization, but I don’t like the idea of having multiple timers in the event loop. If the images could share o single timer, that would be better, I think.

tvler commented 8 years ago

Hi Šime! I'll look into the performance difference of using one interval function. Creating one for each wasn't an optimization design decision, it just seemed clearer to me while programming.

By the way I really appreciate Web Platform Daily : )

agarzola commented 8 years ago

Let me preface this by saying: I may understand timers incorrectly, so please correct me if this is the case.

This conditional:

(rect.bottom >= -offset && rect.top - window.innerHeight < offset) &&
(rect.right >= -offset && rect.left - window.innerWidth < offset)

takes between 0 and 1ms to complete for a single image (it’s rudimentary, but jsperf is down).

Say we have 100 unloaded images that need to be checked continuously, that’s already a significant amount of time, roughly 50-100ms in total. The question is whether we want to set a single setTimeout() that makes the above check for each element in a pre-loaded array of image nodes sequentially with something like a forEach() loop (or for..in for performance). If I’m not mistaken, that’s 50-100ms of blocking execution every time this timer fires.

Now compare that with the current implementation of setting 100 individual setTimeout() timers, each concerned with making the above test for a single image. Even if the environment is slow and the test takes five times as long (5ms) to execute for an image, these executions are queued up independently of one another by virtue of running on separate timers, i.e. they’re not stacked together in strict blocking order the way they would be if invoked from a for..in or forEach loop. The load is distributed more evenly because the event loop is allowed to execute other code in between.

Does that make sense?

tvler commented 8 years ago

I think the memory overhead of dealing with an arbitrary amount of interval'd functions (the current method) may be worse than having one rather large interval function (@simevidas's proposed method). I think I'll make some test pages with an insane amount of scroll-loading images and measure the memory usage for each method.

The best way to close this issue imo is to use some generally approved polyfill for intersection observer. Work for this is being done here https://github.com/WICG/IntersectionObserver/pull/121.