我有一个包含历史记录流的应用程序,其中包含用户操作。历史记录按天或整周显示。在一天中,大约有400-2k个事件要显示。
可能发生的操作类型很少,并且每种操作的显示方式都不同(例如,注释或对象修改)。因此,在每次循环迭代中都有一些逻辑来确定每个元素的最终结构。
问题是渲染需要很多时间,大约1300个元素渲染大约6秒。对我来说,等待这样的事情是相当长的时间。我试图优化代码,以达到所需的最小值,但对于~1300个元素,我能得到的最好结果仍然是6s。
另一个更大的问题是浏览器在渲染过程中冻结,这在这么长的时间内是不可接受的。
我不确定是我做错了什么,还是我发现了一个无法解决的Angular2问题。所以任何提示都是受欢迎的。我对这样的建议不感兴趣:使用分页或使用无限滚动,我正在寻找一种方法,让它更快,更令人窒息。
我还会补充说,以前历史记录是在服务器端呈现的,并且将结果放入DOM中非常快,无论事件的数量如何。进一步的屏幕截图还显示,实际渲染时间只是该过程的一小部分。
我已经在柱塞中准备了渲染代码的简化版本,它显示了问题:http://plnkr.co/edit/QrYmYezmlV3MkQV5bOA8?p=preview
主要的渲染部分:
根ngFor元素
<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>还有一些个人资料记录的截图:


发布于 2017-03-30 02:46:13
Angular 7引入了virtual scroll特性。它可以帮助显着提高渲染性能-只有列表的可见部分被添加到DOM中。但是它也添加了一些限制,比如固定的行大小
发布于 2017-03-30 03:00:05
在Angular中有几种提高性能的好方法。我建议您阅读以下内容:关于使用不可变数据结构来提高性能的http://blog.mgechev.com/2015/03/02/immutability-in-angularjs-immutablejs/。
如果你在阅读后有任何问题,请告诉我。
https://stackoverflow.com/questions/39550229
复制相似问题