ng-web-apis / intersection-observer

A library for idiomatic use of IntersectionObserver with Angular
https://ng-web-apis.github.io/intersection-observer
MIT License
154 stars 4 forks source link

Add debounce / zone #8

Closed RobinKamps closed 3 years ago

RobinKamps commented 4 years ago

🚀 Feature request

Is your feature request related to a problem?

due to this lib changeDetection is called many times, especially if scroll is used in combination with many elements. This is a performance killer on bigger views with many elements and computations. (can easily be checked with ngAfterViewChecked and a console.log)

Describe the solution you'd like

it is easy to debounce all calls wich occur on onIntersect, however this kind of debounce has no effect on changeDetection - wich will still run many times.

to prevent massive change detection runs, the code of the lib should run outside angular in a different zone, e.g. https://stackoverflow.com/questions/32051273/angular-and-debounce

waterplea commented 4 years ago

Hello @RobinKamps. Thanks for your interest in our library! 🙂

I strongly believe in minimal interference with native API as well as minimal extra code and bundled logic. Since the subscription is taking place on the application side, running outside NgZone can be added to the RxJS chain, like the debounce you've mentioned. Please take a look at this code snippet: https://stackblitz.com/edit/angular-zone-free-stream?file=src%2Fapp%2Fzone.operators.ts

We will think about how to handle this case best, thank you for raising this concern. I'm not sure yet how but the snippet above should at least unblock you for the time being.

waterplea commented 3 years ago

Hello again.

So I revisited this subject, sorry for the delay. I believe we should not introduce this to the library. Observer is only triggered upon passing the threshold and for it to be firing too rapidly you have to configure it to have a lot of them. Even scrolling really fast with lots of elements should not introduce performance issues, unless app has problems with it elsewhere.

If you still believe you need to run it outside of zone, here's a little snippet of how you can easily create a debounced and zoneless version of the directive using this library: https://stackblitz.com/edit/intersection-observer-debounce?file=src%2Fapp%2Fdebounced.directive.ts

This is using a tuiZonefree operator from our library Taiga UI (CDK package). It is fully tree-shakable so you can just grab this one operator from it. It is pretty helpful for controlling how your streams are treated by NgZone. Here's the sourcecode if you prefer not to add the library: https://github.com/TinkoffCreditSystems/taiga-ui/blob/main/projects/cdk/observables/zone-free.ts

Another option is to completely disable zone for IntersectionObserver using this flag: (window as any).__Zone_disable_IntersectionObserver = true; You can put it in your polyfills.ts before import "zone.js/dist/zone";