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

Bug: Plugin is calling changeDetection on every mousemove #92

Open
antonbuks opened this issue Nov 7, 2019 · 9 comments
Open

Bug: Plugin is calling changeDetection on every mousemove #92

antonbuks opened this issue Nov 7, 2019 · 9 comments

Comments

@antonbuks
Copy link

antonbuks commented Nov 7, 2019

Reproduction: https://stackblitz.com/edit/ngx-drag-to-select-2bpbcb

If you check the console you will see that every time the mouse moves, the test function is called as a result of change detection. This can be easily fixed by running the plugin outside angular to avoid change detection from eventlisteners.

Event listener:

const mousemove$ = fromEvent<MouseEvent>(window, 'mousemove').pipe( filter(() => !this.disabled), share() );

const mousemove$ = fromEvent<MouseEvent>(window, 'mousemove').pipe(

@d3lm
Copy link
Owner

d3lm commented Nov 8, 2019

So CD actually has to be triggered when the mouse moves, because otherwise the select box won't be re-rendered on the screen and it becomes janky if I audit / throttle it. Curious to hear your thoughts tho.

@antonbuks
Copy link
Author

Ok I see, I haven't had a lot of time this week to look at all the code but I'll have a check this weekend and get back to you.

If you can tell me more precisely how change detection affects re-rendering (point me to some code) that would make it faster.

@bertrandg
Copy link

A nice optimisation for performance would be to subscribe on mousemove only between mousedown and mouseup.
Anyway, thanks for your library ;)

@d3lm
Copy link
Owner

d3lm commented Nov 9, 2019

Good point @bertrandg! I like that. But as I said, we won't be able to run this outside of Angular zone because otherwise the UI won't be updated properly and the selection box won't be re-drawn and throttling it will make it janky. If I remember correctly this is something I tried when I initially built this lib.

@bertrandg
Copy link

Yeah I understand.

Subscribing on mousemove only between mousedown and mouseup is already a big win for the library.

But to go deeper, it would be possible to track all mouse events outside zone.
Here is what is needed inside SelectContainerComponent:

  • Call changeDetectorRef.detach() in constructor.
  • Call changeDetectorRef.detectChanges() when need to refresh select box view (refresh only component view, not whole app).
    [Alternative option is to use directly Renderer2.addClass() / removeClass() / setStyle() / removeStyle() on #selectBox]
  • Wrap all EventEmitter.emit() inside a NgZone.run(() => {...})

@d3lm
Copy link
Owner

d3lm commented Nov 11, 2019

Yep, sounds reasonable. I ll have a look and see which solution I ll go with. Maybe deteching the whole container from the CD cycle might be a good idea. This way I can call CD manually when needed.

@Savers80
Copy link

Savers80 commented Nov 15, 2019

Hi,
i'm novice with Angular, but it's seems naive solution to solve cd on whole app could be:
1- in class KeyboardEventsService
public htmlElement: any = window;
constructor(@Inject(PLATFORM_ID) private platformId: Object) {
if (isPlatformBrowser(this.platformId)) {
this._initializeKeyboardStreams();
}
}
public initializeKeyboardStreams() {
if (isPlatformBrowser(this.platformId)) {
this._initializeKeyboardStreams();
}
}
and change window references to this.htmlElement

2 - SelectContainerComponentin class use :
ngOnInit() {
this.keyboardEvents.htmlElement = this.hostElementRef.nativeElement;
this.keyboardEvents.initializeKeyboardStreams();
}

But this don't solve problem about mouseevents on container triggers CD

I will study EventManagerPlugin to run outsideAngularZone and how integrate it in project, but it is a little hard for me now

@Saonela
Copy link

Saonela commented Apr 28, 2020

Any news on this ?

@d3lm
Copy link
Owner

d3lm commented Apr 28, 2020

Hey @Saonela, my apologies but I haven't had the time yet to delve into this. I am a bit swamped at the moment but if you want to take a stab at it I am more than happy to support you. I would appreciate a PR. First we should upgrade the library to v9 tho. That is also on my todo list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants