通过实现虚拟滚动,提高大型列表的响应速度。
无论是浏览喜爱的社交媒体网站上无限滚动的信息流,还是浏览企业信息中心,滚动列表都是当今最常见的界面模式之一。当滚动列表变得非常长(包含数百、数千或数十万个项)时,应用性能可能会受到影响。
大型列表的加载速度可能会很慢,因为应用必须预先加载并呈现所有数据。此外,由于列表中的每个项目都可能包含丰富的数据、媒体和功能,因此渲染和导航速度也可能较慢。
用户在加载或滚动网页时可能会遇到问题,从而感到沮丧并放弃浏览网页。
使用 Component Dev Kit 在 Angular 中实现虚拟滚动
虚拟滚动是解决这些规模问题的主要技术。 虚拟滚动通过提供大小合适的滚动条,让用户能够浏览列表,而无需应用将整个列表保留在内存中或在网页上呈现。
在 Angular 中,虚拟滚动由 Component Dev Kit (CDK) 提供。通过修改遍历列表的方式并提供一些额外的配置参数,CDK 的虚拟滚动功能将自动管理列表的虚拟渲染,从而提高网页性能和响应能力。
它不会一次性渲染整个列表,而只会渲染适合屏幕大小的一部分项(外加一个小缓冲区)。当用户浏览时,系统会计算并呈现新的项目子集,并根据需要重复使用现有的 DOM。
本文的其余部分将介绍如何设置基本虚拟滚动。 您可以在此示例应用中查看完整的有效示例:
设置虚拟滚动
首先,请确保您已使用自己喜欢的软件包管理器安装 @angular/cdk。如需使用 npm 安装,请在终端中运行以下命令:
npm install --save @angular/cdk
将 ScrollingModule 添加到您的应用
安装 CDK 后,从 @angular/cdk/scrolling 软件包中导入 ScrollingModule,该软件包用于处理虚拟滚动。然后将其添加到模块的 imports 数组中:
import {ScrollingModule} from '@angular/cdk/scrolling';
...
imports: [
ScrollingModule
...
]
...
创建视口
如需了解该软件包的运作方式,请尝试创建一个包含 0 到 99,999 之间数字列表的组件:
@Component({
template: `<div *ngFor="let item of list">{{item}}</div>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
当浏览器渲染应用时,必须渲染 10 万个单独的 <div> 元素。对于基本文本节点,这可能没问题,但重复模板中的任何复杂性都无法很好地扩展,并且任何事件监听器都会成倍增加。
如需添加虚拟滚动并避免这些问题,您需要通过将列表封装在 <cdk-virtual-scroll-viewport> 元素中来创建视口:
@Component({
template: `<cdk-virtual-scroll-viewport>
<div *ngFor="let item of list">{{item}}</div>
</cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
由于 ScrollingModule 会动态渲染列表的子集,因此您必须使用标准 CSS 指定视口的高度。您还需要通过指定 itemSize 为视口提供有关其内容的提示。模块会使用此信息来确定在给定时间要在 DOM 中保留多少项,以及如何渲染大小合适的滚动条。
@Component({
template: `<cdk-virtual-scroll-viewport itemSize="18" style="height:80vh">
<div *ngFor="let item of list">{{item}}</div>
</cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
最后,将 *ngFor 转换为 *cdkVirtualFor:
@Component({
template: `<cdk-virtual-scroll-viewport itemSize="18" style="height:80vh">
<div *cdkVirtualFor="let item of list">{{item}}</div>
</cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
视口不会遍历整个列表,而是会动态识别并遍历列表中的正确子集,以供用户使用。现在,当用户加载网页时,CDK 应渲染适合屏幕大小的列表子集(外加少量缓冲区),并且视口中的任何滚动事件都会加载并渲染相应的列表子集:
深入了解
CDK 的虚拟滚动功能远不止这个基本示例所展示的。在示例应用中,整个列表都位于内存中,但对于更复杂的应用,可以按需提取列表。如需详细了解 ScrollingModule 的其他功能和 cdkVirtualOf 指令,请参阅 CDK 文档中有关 Scrolling 的内容。