我有一个包含用户操作的历史流应用程序。历史记录按天或整周显示。在一天内,大约有大约400-2k的活动可供展示。
可能会发生几种类型的操作,每种操作的显示方式都不同(例如注释或对象修改)。因此,每次循环迭代都有一些逻辑来确定每个元素的最终结构。
问题是它有很多时间渲染,~1300个元素渲染大约6s。对我来说,等待这样的事情已经很久了。我已经尝试优化代码以达到所需的最小值,但是我能得到的最好的是〜1300个元素的6s。
另一个更大的问题是在渲染过程中冻结了浏览器,这在很长一段时间内是不可接受的。
我不确定我是否做错了什么,或者我找到了Angular2的周点,这是无法解决的。所以任何提示都是受欢迎的。 我对以下建议不感兴趣:使用分页或使用无限滚动,我正在寻找一种方法让它更快速地工作和扼杀。
我还要补充一点,以前历史记录是在服务器端呈现的,无论事件的数量如何,将结果放入DOM都非常快。进一步的屏幕截图还显示,实际渲染时间只是整个过程的一小部分。
我在plunker中准备了渲染代码的简化版本,显示了问题: http://plnkr.co/edit/QrYmYezmlV3MkQV5bOA8?p=preview
主要渲染部分:
Root ngFor element
<div class="history-stream">
<div *ngFor="let action of history"
class="activity" [ngClass]="{'first-of-user': action.firstOfUser, 'last-of-user': action.lastOfUser}">
<p class="date" *ngIf="action.firstOfDay">{{ action.date | date:'mediumDate' }}</p>
<div class="user-entry" [ngSwitch]="action.type">
<comment *ngSwitchCase="'comment'" [object]="action"></comment>
<modified *ngSwitchCase="'modified'" [object]="action"></modified>
</div>
</div>
</div>
评论组件:
<div class="entry comment" [ngClass]="{'comment-resolved': object.extra.is_resolved}">
<a href="{{ getDeleteUrl(object.extra.comment_id) }}" data-target="metabase-modal-ajax" class="comment-action">Delete</a>
<a href="#" class="comment-action" *ngIf="!object.extra.is_resolved" (click)="resolveComment($event)">Mark as resolved</a>
<a href="#" class="comment-action" *ngIf="object.extra.is_resolved" (click)="unResolveComment($event)">Unresolve</a>
<p class="action" [innerHTML]="object.action"></p>
<p>{{ object.comment }}</p>
<small class="text-muted">{{ object.date | date:'shortTime' }} <span class="dot">·</span> {{ object.date | date:'shortTime' }}</small>
</div>
修改后的事件组件:
<div class="entry modified">
<p class="action" [innerHTML]="object.action"></p>
<ul class="changes list-unstyled">
<li *ngFor="let change of object.changes">
<span class="attribute">{{ change.attribute }}:</span>
<modified-value [change]="change.from"></modified-value>
<span class="arrow">→</span>
<modified-value [change]="change.to"></modified-value>
<small class="time text-muted">{{ change.date | date:'shortTime' }} <span class="dot">·</span> {{ change.date | date:'shortTime' }}</small>
</li>
</ul>
</div>
和修改后的价值组件:
<span [ngSwitch]="getChangeType()">
<span *ngSwitchCase="'complex'">
<span *ngFor="let item of change">
<span class="badge">{{ item.tag }}</span>
<span [ngSwitch]="isArray(item.value)">
<span *ngSwitchCase="true">
<span *ngFor="let valueItem of item.value" class="value tag">{{ valueItem }}</span>
<span *ngIf="isEmpty(item.value)" class="value text-muted">None</span>
</span>
<span *ngSwitchCase="false">
<span *ngIf="item.value" class="value">{{ item.value }}</span>
<span *ngIf="!item.value" class="value text-muted">None</span>
</span>
</span>
</span>
</span>
<span *ngSwitchDefault>
<span *ngIf="change" class="value">{{ change }}</span>
<span *ngIf="!change" class="value text-muted">None</span>
</span>
</span>
还有一些个人资料的截图:
答案 0 :(得分:1)
Angular 7引入了virtual scroll功能。它可以帮助显着提高渲染性能 - 只有可见的部分列表被添加到DOM中。但它也增加了一些限制,例如固定行大小
答案 1 :(得分:-1)
有一些提高Angular性能的好方法。我建议你阅读:http://blog.mgechev.com/2015/03/02/immutability-in-angularjs-immutablejs/关于使用不可变数据结构来提高性能。
如果您在阅读后有任何问题,请告诉我。