Kendo-angular: Kendo UI DatePicker + Simplebar browser freeze / crash

Created on 2 Feb 2018  路  2Comments  路  Source: telerik/kendo-angular

I'm submitting a...

Bug report

Current behavior

Kendo UI DatePicker causes browser to freeze forever when there is Simplebar instantiated on the page.

Expected behavior

Browser shouldn't freeze and datepicker should be opened

Minimal reproduction of the problem with instructions

I've created repository to reproduce the issue. It's not easy to reproduce and I cannot provide a piece of code to reproduce it.

Environment

Browser:

  • Chrome (desktop) version 63
  • Safari (desktop) version 11.0.2

System:

  • TypeScript version: 2.5.3
  • Node version: 6.10.0 / 5.6.0
  • Platform: Mac
Question date-inputs

Most helpful comment

I reviewed the attached repro demo and was able to observe the described behavior. Indeed the page hangs when the one tries to open the DatePicker.

After a through investigation we found out that the cause of the issue is the ResizeObserver used in the SimpleBar widget. Basically, it will listen to multiple changes in the page, which will cause the NgZone to run an App change detection cycle, which in turn will cause more mutations on the page. At this point, the page will hang forever.

The solution is to put the SimpleBar initialization outside the Angular zone. You will need to tweak the custom directive implementation to utilize this approach:

@Directive({
  selector: '[appSimpleBar]'
})
  export class SimpleBarDirective implements AfterViewInit {

  private SimpleBar = getSimpleBarInstance();
  private _simpleBar: any;

  @Output() scrollReachedBottom: EventEmitter<any> = new EventEmitter<any>();

  constructor(private elementRef: ElementRef, private zone: NgZone) { }

  ngAfterViewInit() {
    const self = this;

    this.zone.runOutsideAngular(() => {
        this._simpleBar = new this.SimpleBar(this.elementRef.nativeElement, {
          autoHide: true
        });

        this.elementRef.nativeElement.SimpleBar.getScrollElement().addEventListener('scroll', (event) => {
          const target = event.target;

          if ((target.clientHeight + target.scrollTop) >= target.scrollHeight) {
            self.scrollReachedBottom.emit();
          }
        });
    });
  }
}

Please note that although the DatePicker causes the page to hang, the discussed erroneous behavior is not directly to the component. Most components that append an element to the page will cause the same behavior due to the specifics of the NgZone implementation.

Will close the thread as it does not report a bug in the component or suggests a possible enhancement.

All 2 comments

I reviewed the attached repro demo and was able to observe the described behavior. Indeed the page hangs when the one tries to open the DatePicker.

After a through investigation we found out that the cause of the issue is the ResizeObserver used in the SimpleBar widget. Basically, it will listen to multiple changes in the page, which will cause the NgZone to run an App change detection cycle, which in turn will cause more mutations on the page. At this point, the page will hang forever.

The solution is to put the SimpleBar initialization outside the Angular zone. You will need to tweak the custom directive implementation to utilize this approach:

@Directive({
  selector: '[appSimpleBar]'
})
  export class SimpleBarDirective implements AfterViewInit {

  private SimpleBar = getSimpleBarInstance();
  private _simpleBar: any;

  @Output() scrollReachedBottom: EventEmitter<any> = new EventEmitter<any>();

  constructor(private elementRef: ElementRef, private zone: NgZone) { }

  ngAfterViewInit() {
    const self = this;

    this.zone.runOutsideAngular(() => {
        this._simpleBar = new this.SimpleBar(this.elementRef.nativeElement, {
          autoHide: true
        });

        this.elementRef.nativeElement.SimpleBar.getScrollElement().addEventListener('scroll', (event) => {
          const target = event.target;

          if ((target.clientHeight + target.scrollTop) >= target.scrollHeight) {
            self.scrollReachedBottom.emit();
          }
        });
    });
  }
}

Please note that although the DatePicker causes the page to hang, the discussed erroneous behavior is not directly to the component. Most components that append an element to the page will cause the same behavior due to the specifics of the NgZone implementation.

Will close the thread as it does not report a bug in the component or suggests a possible enhancement.

Wow! Thanks for the investigation!

Was this page helpful?
0 / 5 - 0 ratings