实现虚拟滚动,使大型列表的响应速度更快。
无论是在您喜爱的社交媒体网站上浏览可无限滚动的信息流,还是在企业信息中心内导航,滚动列表是目前最常见的界面模式之一。当滚动列表变得很长(成百上千或数十万项)时,应用性能会受到影响。
大型列表的加载速度可能很慢,因为应用必须预先加载并呈现所有数据。它们的呈现和浏览速度也可能会很慢,因为列表中的每一项都可能具有丰富的数据、媒体内容和功能。
用户在加载或滚动页面时可能会遇到问题,导致用户感到沮丧和放弃页面。
使用组件开发套件在 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
。
主打图片,创作者:Mr Cup / Fabien Barral 在 Unsplash 用户。