From c26dc74e7dc0b061b929a91cd16f075e0898a415 Mon Sep 17 00:00:00 2001 From: nename0 <26363498+nename0@users.noreply.github.com> Date: Fri, 21 Sep 2018 19:01:38 +0200 Subject: [PATCH] perf(virtual-scroll): use auditTime instead of sampleTime (#13131) The `CdkVirtualScrollViewport` uses `sampleTime` to collect multiple scroll events into one until the next animation frame. However the `sampleTime` also samples even if there is no new upstream values. Which in this case creates an basically useless requestAnimationFrame callback. A better choice would be the `auditTime` operator, which only schedules the requestAnimationFrame when there is actually a new upstream value. In our case it has the exact same behavior, as from looking at the performance profiler in chrome I found out this: first the scroll event fires, then pending requestAnimationFrame callbacks get called, regardless if they where scheduled in the current or previous frame and then the paint occurs. --- src/cdk/scrolling/virtual-scroll-viewport.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cdk/scrolling/virtual-scroll-viewport.ts b/src/cdk/scrolling/virtual-scroll-viewport.ts index 01910cc95130..da9014da345e 100644 --- a/src/cdk/scrolling/virtual-scroll-viewport.ts +++ b/src/cdk/scrolling/virtual-scroll-viewport.ts @@ -24,7 +24,7 @@ import { ViewEncapsulation, } from '@angular/core'; import {animationFrameScheduler, Observable, Subject} from 'rxjs'; -import {sampleTime, startWith, takeUntil} from 'rxjs/operators'; +import {auditTime, startWith, takeUntil} from 'rxjs/operators'; import {ScrollDispatcher} from './scroll-dispatcher'; import {CdkScrollable, ExtendedScrollToOptions} from './scrollable'; import {CdkVirtualForOf} from './virtual-for-of'; @@ -144,9 +144,10 @@ export class CdkVirtualScrollViewport extends CdkScrollable implements OnInit, O .pipe( // Start off with a fake scroll event so we properly detect our initial position. startWith(null!), - // Sample the scroll stream at every animation frame. This way if there are multiple - // scroll events in the same frame we only need to recheck our layout once. - sampleTime(0, animationFrameScheduler)) + // Collect multiple events into one until the next animation frame. This way if + // there are multiple scroll events in the same frame we only need to recheck + // our layout once. + auditTime(0, animationFrameScheduler)) .subscribe(() => this._scrollStrategy.onContentScrolled()); this._markChangeDetectionNeeded();