diff --git a/src/cdk/overlay/position/flexible-connected-position-strategy.ts b/src/cdk/overlay/position/flexible-connected-position-strategy.ts index e0604d8f1309..0786f1ff81ef 100644 --- a/src/cdk/overlay/position/flexible-connected-position-strategy.ts +++ b/src/cdk/overlay/position/flexible-connected-position-strategy.ts @@ -108,9 +108,19 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { /** Selector to be used when finding the elements on which to set the transform origin. */ private _transformOriginSelector: string; + /** Amount of subscribers to the `positionChanges` stream. */ + private _positionChangeSubscriptions = 0; + /** Observable sequence of position changes. */ - positionChanges: Observable = - this._positionChanges.asObservable(); + positionChanges: Observable = Observable.create(observer => { + const subscription = this._positionChanges.subscribe(observer); + this._positionChangeSubscriptions++; + + return () => { + subscription.unsubscribe(); + this._positionChangeSubscriptions--; + }; + }); /** Ordered list of preferred positions, from most to least desirable. */ get positions() { @@ -581,9 +591,14 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { this._lastPosition = position; // Notify that the position has been changed along with its change properties. - const scrollableViewProperties = this._getScrollVisibility(); - const changeEvent = new ConnectedOverlayPositionChange(position, scrollableViewProperties); - this._positionChanges.next(changeEvent); + // We only emit if we've got any subscriptions, because the scroll visibility + // calculcations can be somewhat expensive. + if (this._positionChangeSubscriptions > 0) { + const scrollableViewProperties = this._getScrollVisibility(); + const changeEvent = new ConnectedOverlayPositionChange(position, scrollableViewProperties); + this._positionChanges.next(changeEvent); + } + this._isInitialRender = false; }