mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user