前台性能优化总结

11次阅读

共计 1617 个字符,预计需要花费 5 分钟才能阅读完成。

场景
某天上完课,走在路上,突然想起来,一个企业中,计算机量可能很大,500 到 2000 左右。
分组时,可能会很耗时,前台能不能承受的住。

模拟加了 1000 台计算机,前台直接炸,将近 4 秒才能出来,并且选择的时候也很卡。
学习了很多数据量多时性能优化的方法,目前前台经过一系列优化,能保证在 Chrome 浏览器环境、1000 台测试机的条件下,,2s 内完成页面渲染。
优化
组件介绍

前台多选使用的是 NZ 为我们提供的多选框组件,该组件要求输入信息必须满足一定格式。
/**
* NZ 多选框
* nz-checkbox-group
* 数据格式规范
*/
export class NzCheckBoxSpec<T> {
label: string;
value: T;
checked: boolean;
}
所以,计算机多选组件整体逻辑如下:

获取外部传入的计算机列表 (考虑到默认选中的问题)。
从后台查询所有的计算机列表。
根据所有计算机构造 NZ 多选框组件的输入,checked 一项根据当前遍历的计算机是否在传入的计算机列表中判断。

性能问题
看着问题不大:
this.hostService.getAllHosts().subscribe((hosts) => {
this.hostListValues = [];
// 使用主机信息构造多选框绑定数据
hosts.forEach((host) => {
this.hostListValues.push({
label: host.name,
value: host,
checked: HostCheckboxComponent.existIn(host, this._hostList)
});
});
});
查阅相关资料,原来一直都用的有问题,forEach 虽然很好使,但是是性能最低的一种循环。
性能测试
我亲自写测试代码测试三种循环方式的性能 (数据量 2000,内部执行同样业务操作):

实验次数 / 实验方法
forEach
for of
for

1
654ms
524ms
517ms

2
604ms
571ms
563ms

3
550ms
506ms
508ms

4
621ms
495ms
522ms

5
506ms
562ms
470ms

平均时间
587ms
531.6ms
516ms

我这里只是部分少量数据,结果具有随机性,不具有普遍性。
反正这里我是总结出几点:

当数据量少的时候,我使用 forEach,方便。
当数据量大的时候,我是用 for 循环,性能略好。
当需要在循环中 return 时,使用 for of,方便。

学习过程中还查到了 Duff’s Device,这是目前性能最好的循环方式。有人测试,Duff’s Device 需要达到 30 万的数据量才能显示其算法高效的性能。
组件的错误使用
最开始,组件是这样使用的。
<app-host-checkbox [hostList]=”hostGroup.hostList”
(hostCheck)=”bindHostList($event)”></app-host-checkbox>
看着没啥毛病啊,把计算机组的 hostList 传进去,然后一个输出事件,绑定 hostCheck 事件,当选中的计算机有改动的时候就调用 bindHostList() 方法。
bindHostList(hostList: Array<Host>): void {
this.hostGroup.hostList = hostList;
}
注意看这张图:

页面把 hostGroup 的 hostList 传给组件。
组件初始化,当用户选择的时候,再把选中的值回传给 hostGroup。

hostGroup 的 hostList 变了,又传给组件了。

所以,组件初始化执行了两次,本来 for 循环就已经很耗时了,更何况执行两次。之前测试数据少没发现。
新建临时变量,该变量只用于传输入的 hostList。
总结
在校学习过的东西,我们总是很久以后用到。
如果不是华软项目,也用不到学过的计算机网络,没有大数据量,学的算法复杂度也用不上。
当编码不是问题的时候,我们开始考虑设计与用户体验。

正文完
 0