message: perf(dropdown): reduce the number of document click listeners
  * perf(dropdown): reduce the number of document click listeners
  Edit document click listeners to be added only for open dropdowns which improves overall page performance in case of a large number of dropdowns.
diff: import {
  + ChangeDetectorRef,
  Directive,
  ElementRef,
  HostBinding,
  HostListener,
  - OnDestroy
  + OnDestroy,
  + Renderer2
  } from '@angular/core';
  -import { Subscription } from 'rxjs';
  +import { Subscription } from 'rxjs';
  import { BsDropdownState } from './bs-dropdown.state';
  import { BsDropdownDirective } from './bs-dropdown.directive';
  @@ -19,19 +21,50 @@ import { BsDropdownDirective } from './bs-dropdown.directive';
  })
  export class BsDropdownToggleDirective implements OnDestroy {
  @HostBinding('attr.disabled') isDisabled: boolean = null;
  -
  - // @HostBinding('class.active')
  @HostBinding('attr.aria-expanded') isOpen: boolean;
  private _subscriptions: Subscription[] = [];
  + private _documentClickListener: Function;
  + private _escKeyUpListener: Function;
  - constructor(private _state: BsDropdownState, private _element: ElementRef, private dropdown: BsDropdownDirective) {
  + constructor(
  + private _changeDetectorRef: ChangeDetectorRef,
  + private _dropdown: BsDropdownDirective,
  + private _element: ElementRef,
  + private _renderer: Renderer2,
  + private _state: BsDropdownState
  + ) {
  // sync is open value with state
  this._subscriptions.push(
  this._state.isOpenChange.subscribe(
  - (value: boolean) => (this.isOpen = value)
  + (value: boolean) => {
  + this.isOpen = value;
  +
  + if (value) {
  + this._documentClickListener = this._renderer.listen('document', 'click', (event: any) => {
  + if (this._state.autoClose && event.button !== 2 &&
  + !this._element.nativeElement.contains(event.target) &&
  + !(this._state.insideClick && this._dropdown._contains(event))
  + ) {
  + this._state.toggleClick.emit(false);
  + this._changeDetectorRef.detectChanges();
  + }
  + });
  +
  + this._escKeyUpListener = this._renderer.listen(this._element.nativeElement, 'keyup.esc', () => {
  + if (this._state.autoClose) {
  + this._state.toggleClick.emit(false);
  + this._changeDetectorRef.detectChanges();
  + }
  + });
  + } else {
  + this._documentClickListener();
  + this._escKeyUpListener();
  + }
  + }
  )
  );
  +
  // populate disabled state
  this._subscriptions.push(
  this._state.isDisabledChange.subscribe(
  @@ -48,25 +81,6 @@ export class BsDropdownToggleDirective implements OnDestroy {
  this._state.toggleClick.emit(true);
  }
  - @HostListener('document:click', ['$event'])
  - onDocumentClick(event: MouseEvent): void {
  - if (
  - this._state.autoClose &&
  - event.button !== 2 &&
  - !this._element.nativeElement.contains(event.target) &&
  - !(this._state.insideClick && this.dropdown._contains(event))
  - ) {
  - this._state.toggleClick.emit(false);
  - }
  - }
  -
  - @HostListener('keyup.esc')
  - onEsc(): void {
  - if (this._state.autoClose) {
  - this._state.toggleClick.emit(false);
  - }
  - }
  -
  ngOnDestroy(): void {
  for (const sub of this._subscriptions) {
  sub.unsubscribe();
  