gpt4 book ai didi

javascript - 改进 Angular 中的 ng-repeat(只读 html 表格)渲染性能

转载 作者:行者123 更新时间:2023-12-01 17:55:40 25 4
gpt4 key购买 nike

我已经阅读了六篇关于使用 ng-repeat 提高性能的文章,但到目前为止,我还没有找到一种直接的方法来改进简单绑定(bind)一次表的呈现。

我分析了各种方法,到目前为止,我能做的最好的是 5 秒渲染时间约 4400 行。

** 关于这个测试用例的注释。我正在使用更大的数据集将性能测试推向具有挑战性的数据集。通常情况下,该表将有 1000 行或更少。我想避免分页,因为在许多情况下,查看所有数据对于扫描异常情况很有用。更重要的是,300 行的渲染时间对我来说也是不能接受的,因为它会在短时间内卡住浏览器,而这正是我想要消除的。我完全知道渲染更少的数据会更快,我正在考虑最大化更大数据集的性能。

我最初的做法

<tbody>
<tr ng-repeat="f in vm.rowDetails">
<td class="checkbox-column"><input type="checkbox" ng-model="f.selected" /></td>
<td class="w100">{{f.Code}}</td>
<td class="w50">{{f.Class}}</td>
<td>{{f.WebName}}</td>
<td>{{f.Category}}</td>
<td>{{f.MktgCode}}</td>
</tr>
</tbody>

渲染 ~ 7 秒

添加了 bind once 属性(自 angular 1.3 起可用)(尽管它不适用于 ng-repeat 指令

<tbody>
<tr ng-repeat="f in vm.rowDetails">
<td class="checkbox-column"><input type="checkbox" ng-model="f.selected" /></td>
<td class="w100">{{::f.Code}}</td>
<td class="w50">{{::f.Class}}</td>
<td>{{::f.WebName}}</td>
<td>{{::f.Category}}</td>
<td>{{::f.MktgCode}}</td>
</tr>
</tbody>

没有明显的改善。我想这在某种程度上是意料之中的,因为这优化了后续的监视周期。

开始尝试进行我自己的行字符串连接。

<tbody>
<tr pm-table-row f="f" ng-repeat="f in vm.rowDetails track by $index"></tr>
</tbody>

指令:

angular.module('app').directive('pmTableRow', ['$interpolate', function ($interpolate) {
var template2 = '' +
'<td class="checkbox-column"><input type="checkbox" ng-model="f.selected" /></td> ' +
'<td class="w100">Code</td>' +
'<td class="w50">Class</td>' +
'<td>WebName</td>' +
'<td>Category</td>' +
'<td>MktgCode</td>';
return {
restrict: 'A',
replace: false,
scope: { f: '=' },
link: function ($scope, $element, $attr) {
var fields = ['Code', 'Class', 'WebName', 'Category', 'MktgCode'];
var t = template2;
var f = $scope.f;
for (var k in fields)
t = t.replace(fields[k], f[fields[k]]);

$element.html(t);
}
}}]);

这似乎是一个改进,但不是很大。渲染时间缩短到 ~4.7 秒

最后我尝试完全删除 ng-repeat,并在我的指令中生成 tBody 字符串

<tbody pm-table-body items="vm.rowDetails">

指令:

angular.module('app').directive('pmTableBody', ['$interpolate', function ($interpolate) {
var template2 = '' +
'<tr><td class="checkbox-column"><input type="checkbox" ng-model="f.selected" /></td> ' +
'<td class="w100">Code</td>' +
'<td class="w50">Class</td>' +
'<td>WebName</td>' +
'<td>Category</td>' +
'<td>MktgCode</td></tr>';
return {
restrict: 'A',
replace: false,
scope: { items: '=' },
link: function ($scope, $element, $attr) {
var fields = ['Code', 'Class', 'WebName', 'Category', 'MktgCode'];
var lines = [];

$scope.$watch('items', function () {
var items = $scope.items;
var t1 = new Date();
var t = template2;
for (var i = 0; i < items.length; i++) {
var f = items[i];
for (var k in fields) {
t = t.replace(fields[k], f[fields[k]]);
lines.push(t);
}
}
console.log('pmTableBody html concatenation done in: ', (new Date() - t1)/1000); // done in 0.02 seconds
$element.html(lines.join(''));
});
}
}}]);

出于某种原因,这将渲染时间增加到 28 秒.. 所以我可能在这里遗漏了一些明显的东西。

我想将渲染时间缩短到 < 1 秒。

更新 我通过在我的复制对象上创建一个唯一的 id 字段来删除 $index 的跟踪。到目前为止,性能没有明显变化,但我会继续努力。

更新我添加了一个基于 this post 的 watch 计数器.结果如下:使用 4400 行和 ng-repeat 方法,有 26,102 个观察者使用 tr pm-table-row 方法,有 4457 个观察者,最后使用 pm-table-body 方法,有 57 个观察者!有趣的是,这是迄今为止性能最慢的方法。

更新有趣的是,在进一步分析之后,pm-table-body 方法似乎使用了很多 Angular 动画功能。 enter image description here

禁用动画后,(程序) 占用了 10 秒 enter image description here

所以浏览器在很长一段时间内仍然没有响应,仍在对那里发生的事情进行故障排除。

最佳答案

如果您想提高渲染性能,您应该使用 limitTo 过滤器并在您的页面上实现分页,另一种方法是使用此 ngInfiniteScroll directive在一页上查看整个表格。

如果你想知道这个表中的某种搜索,另一个过滤器 ng-repeat="item in items | filter:searchString"将应用于整个数据集,不仅适用于你的有限 View ,而且你需要记住的是,filter 过滤器应该在 limitTo 之前先跟随。

关于javascript - 改进 Angular 中的 ng-repeat(只读 html 表格)渲染性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30219721/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com