Angular 我们如何利用角度变化检测来提高性能?
我正在创建我的第一个开源项目,一本学校成绩册。我是新手。 问题:如何提高成绩册应用程序的运行时性能?表单控件是根据学生和作业动态生成的。渲染所花费的时间超出预期 我尝试分离变更检测器,但在触发变更检测时仍然花费了太多时间 当我研究chrome开发工具时,大部分时间都花在变化检测上Angular 我们如何利用角度变化检测来提高性能?,angular,typescript,angular2-changedetection,Angular,Typescript,Angular2 Changedetection,我正在创建我的第一个开源项目,一本学校成绩册。我是新手。 问题:如何提高成绩册应用程序的运行时性能?表单控件是根据学生和作业动态生成的。渲染所花费的时间超出预期 我尝试分离变更检测器,但在触发变更检测时仍然花费了太多时间 当我研究chrome开发工具时,大部分时间都花在变化检测上 private createFormControls( ) { const gradeGroup = this.gradeControls; this.clearAllGradeControls(
private createFormControls( ) {
const gradeGroup = this.gradeControls;
this.clearAllGradeControls(gradeGroup);
for (let i = 0; i < this.gradebook.students.length; i++) {
const student = this.gradebook.students[i];
const studentGrades = this.gradebook.grades.filter( g => g.userId == student.userId);
for (let j = 0; j < this.gradebook.assignments.length; j++) {
const assignment = this.gradebook.assignments[j];
const key = this.createKey(student.userId, assignment.id);
const grade = studentGrades.find( g => g.assignmentId == assignment.id );
let fg = new FormGroup({
grade: new FormControl(grade ? grade.grade : ''),
userId: new FormControl(student.userId),
assignmentId: new FormControl(assignment.id),
});
gradeGroup.addControl(key, fg);
}
}
}
private createFormControls(){
const gradeGroup=this.gradeControls;
此.clearAllGradeControls(gradeGroup);
for(设i=0;ig.userId==student.userId);
对于(设j=0;jg.assignmentId==assignment.id);
设fg=newformgroup({
等级:新FormControl(等级?等级。等级:“”),
userId:newformcontrol(student.userId),
assignmentId:new FormControl(assignment.id),
});
gradeGroup.addControl(键,fg);
}
}
}
闪电战
Github:
如何以更好的性能动态生成表单控件的行和列
更新
在研究了导致整体性能出现主要问题的原因之后,更改检测在很大程度上会减慢组件的速度。我试图将数据数组转换为RxJS observable。我仍在努力进行变化检测
关于有效使用变更检测的“正确”模式/架构有什么建议吗?我很惊讶地认为变更检测会给您带来这个问题,直到我意识到它不是。你看到的是假阳性。真正的瓶颈在于将沉重的
FormGroup
分配/呈现给
元素(在运行更改检测并更新值时恰好发生这种情况)
我打算建议使用Angular来“绕过”修改FormGroup
时发生的所有更改检测,但这不会有多大区别(我测试了它,然后意识到真正的问题在别处)。实际上,我建议仍然这样做,不是出于性能原因,而是出于架构原因。我会将所有逻辑移到一个服务,然后让警卫注入该服务并使用它调用解析调用
真正的问题在于表单包含的FormGroups
的数量。您将通过39列查看25人=975FormGroups
。每个FormGroups
包含3个FormControls
,总计将近3000个。这是一个巨大的问题,我不相信有任何现成的解决方案
我建议做的是在任何给定时间尽量减少可见字段的数量(因为没有人希望看到前面的975个字段)。您可以将*ngFor
元素拆分为更小的、已拆分的*ngFor
元素,然后将其中一些元素封装在一些*ngIf
逻辑中,这样它们就不会总是被渲染(例如,当当前滚动位置接近元素顶部时,*ngIf
可能会计算为true)
您可以做的另一件事是研究更复杂的*ngFor
元素的延迟加载。我发现了一个有趣的例子,作者通过创建一个“lazy”*ngFor
指令来运行您。我不能保证它的质量(或可行性),但它绝对值得一试
像往常一样,OnPush
更改检测几乎是必须的,在这种情况下,这将有助于提高性能
如果我想到别的什么,我会回来编辑这篇文章
祝你好运
编辑:
角度CDK支持内置的。您可以使用
标记创建一个可滚动的容器,然后将*ngFor
指令替换为*cdkVirtualFor
。API的其余部分是相同的
简要引用以下文件:
仅通过在屏幕上呈现适合的项目来高效地显示大型元素列表。在任何浏览器中加载数百个元素都可能很慢;通过使容器元素的高度与要渲染的元素总数的高度相同,然后仅渲染视图中的项目,虚拟滚动启用了一种性能方法来模拟正在渲染的所有项目
我很惊讶地认为ChangeDetection会给您带来这个问题,直到我意识到它不是。你看到的是假阳性。真正的瓶颈在于将沉重的
FormGroup
分配/呈现给
元素(在运行更改检测并更新值时恰好发生这种情况)
我打算建议使用Angular来“绕过”修改FormGroup
时发生的所有更改检测,但这不会有多大区别(我测试了它,然后意识到真正的问题在别处)。实际上,我建议仍然这样做,不是出于性能原因,而是出于架构原因。我会将所有逻辑移到一个服务,然后让警卫注入该服务并使用它调用解析调用
真正的问题在于表单包含的FormGroups
的数量。您将通过39列查看25人=975FormGroups
。每一个