perf(virtual-scroll): improve scrolling performance (#12490)

Adds contain and translateZ to viewport and wrapper CSS and switches spacer to use transform instead of width/height
This commit is contained in:
mmalerba
2018-08-03 07:02:38 -07:00
committed by Jeremy Elbourn
parent 674ebcd925
commit 4a9fe87f8a
3 changed files with 28 additions and 7 deletions
@@ -9,7 +9,4 @@
Spacer used to force the scrolling container to the correct size for the *total* number of items
so that the scrollbar captures the size of the entire data set.
-->
<div class="cdk-virtual-scroll-spacer"
[style.height.px]="orientation === 'horizontal' ? 1 : _totalContentSize"
[style.width.px]="orientation === 'horizontal' ? _totalContentSize : 1">
</div>
<div class="cdk-virtual-scroll-spacer" [style.transform]="_totalContentSizeTransform"></div>
+18 -2
View File
@@ -32,6 +32,9 @@ cdk-virtual-scroll-viewport {
display: block;
position: relative;
overflow: auto;
contain: strict;
transform: translateZ(0);
will-change: scroll-position;
}
// Wrapper element for the rendered content. This element will be transformed to push the rendered
@@ -40,7 +43,8 @@ cdk-virtual-scroll-viewport {
position: absolute;
top: 0;
left: 0;
will-change: contents, transform;
contain: content;
will-change: transform;
}
.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper {
@@ -57,5 +61,17 @@ cdk-virtual-scroll-viewport {
// set if it were rendered all at once. This ensures that the scrollable content region is the
// correct size.
.cdk-virtual-scroll-spacer {
will-change: height, width;
position: absolute;
top: 0;
left: 0;
height: 1px;
width: 1px;
transform-origin: 0 0;
will-change: transform;
[dir='rtl'] & {
right: 0;
left: auto;
transform-origin: 100% 0;
}
}
+9 -1
View File
@@ -77,10 +77,16 @@ export class CdkVirtualScrollViewport implements OnInit, OnDestroy {
/** A stream that emits whenever the rendered range changes. */
renderedRangeStream: Observable<ListRange> = this._renderedRangeSubject.asObservable();
/**
* The transform used to scale the spacer to the same size as all content, including content that
* is not currently rendered.
*/
_totalContentSizeTransform = '';
/**
* The total size of all content (in pixels), including content that is not currently rendered.
*/
_totalContentSize = 0;
private _totalContentSize = 0;
/**
* The CSS transform applied to the rendered subset of items so that they appear within the bounds
@@ -211,6 +217,8 @@ export class CdkVirtualScrollViewport implements OnInit, OnDestroy {
setTotalContentSize(size: number) {
if (this._totalContentSize !== size) {
this._totalContentSize = size;
const axis = this.orientation == 'horizontal' ? 'X' : 'Y';
this._totalContentSizeTransform = `scale${axis}(${this._totalContentSize})`;
this._markChangeDetectionNeeded();
}
}