javascript 使用 AngularJS 的 ng-repeat 渲染使 IE11 变慢/冻结
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30443986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IE11 slow / freeze with AngularJS's ng-repeat rendering
提问by Fabrizio A
Currently I have a very sublte problem to solve with IE11 and AngularJS.
目前我有一个非常微妙的问题需要用 IE11 和 AngularJS 来解决。
My page consists of two nested ng-repeat to create a tabset with a table inside any tab.
我的页面由两个嵌套的 ng-repeat 组成,用于在任何选项卡内创建一个带有表格的选项卡集。
Here the code: http://pastebin.com/0fffPz5Z
这里的代码:http: //pastebin.com/0fffPz5Z
In the code, each application's object have around 1.000 item's related objects. With a Chrome, Safari and Mozilla I have no problem, all is superfast! With IE11 the page go slow and IE11 show me the message of a too slow page's script....
在代码中,每个应用程序的对象都有大约 1.000 个项目的相关对象。使用 Chrome、Safari 和 Mozilla 我没有问题,一切都超快!使用 IE11 页面变慢,IE11 向我显示页面脚本太慢的消息....
I've created an IE11 interface's profiling with this result: https://www.dropbox.com/s/y5xuystxht6gjkr/IE11-interface-profiling.png?dl=0
我用这个结果创建了一个 IE11 界面的分析:https://www.dropbox.com/s/y5xuystxht6gjkr/IE11-interface-profiling.png?dl =0
Is this another IE11's bug??? Sorry for my English and thanks in advance for any suggestion.
这是另一个IE11的错误吗???抱歉我的英语,并提前感谢您的任何建议。
Edit: Currently (for "debug" purpose) I removed all td's content... the IE11 is still too slow. :(
编辑:目前(出于“调试”目的)我删除了所有 td 的内容...... IE11 仍然太慢。:(
<tabset ng-show="!applicationsLoading">
<tab ng-repeat="application in applications track by application.name">
<tab-heading>
<em class="fa fa-clock-o fa-fw"></em> {{ application.name }}
</tab-heading>
<div>
<!-- START table responsive-->
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in application.items track by item.itemid">
<td></td>
<td></td>
<td>
</td>
<td></td>
<td></td>
<td>
</td>
<!-- Graph or History column -->
<td>
</td>
</tr>
</tbody>
</table>
</div>
<!-- END table responsive-->
</div>
</tab>
</tabset>
回答by nesteant
AngularJs has limits for rendering bindings per page (In some articles you can find that it is around 2000 bindings). Currently you've just faced this situation. The reason why chrome and Mozilla work smoothly is that DOM operations for them are optimized better. In order to improve your performance try to:
AngularJs 对每页渲染绑定有限制(在一些文章中你会发现它大约有 2000 个绑定)。目前您刚刚面临这种情况。chrome 和 Mozilla 之所以能流畅运行,是因为对它们的 DOM 操作优化得比较好。为了提高您的性能,请尝试:
- avoid using sort in ng-repeat (sort it before insertions)
- Use one-time bindings (:: syntax)
- Remove unnecessary watches
- Optimize digest cycles
- Use pagination
- Replace angularjs ng-repeat with ReactJs components (in case of really big amount of data)
- 避免在 ng-repeat 中使用 sort (在插入之前对其进行排序)
- 使用一次性绑定(:: 语法)
- 删除不必要的手表
- 优化消化周期
- 使用分页
- 用 ReactJs 组件替换 angularjs ng-repeat(在数据量非常大的情况下)
回答by amallard
Just ran into this same problem. Had everything working perfectly on Chrome, then tested in IE and it kept crashing with anything over 1000 records.
刚刚遇到了同样的问题。让一切在 Chrome 上完美运行,然后在 IE 中进行测试,并且它不断崩溃,超过 1000 条记录。
I ended up following this linkto add a "lazy load" or "infinite scroll" to my table. So on table load it still pulls all 1000+ records, but instead of loading this data directly into the table, I load it into a big array, then just subset my table of say 50 records. Then create a directive that listens to the scroll on the table, and when it's near the bottom then fire off a function which just adds the next 50 records from the big array into my table array. Here's a direct link to the fiddlefrom the link above.
我最终按照此链接向我的表格添加了“延迟加载”或“无限滚动”。因此,在表加载时,它仍会提取所有 1000 多条记录,但我没有将这些数据直接加载到表中,而是将其加载到一个大数组中,然后将我的表子集化为 50 条记录。然后创建一个指令来监听表格上的滚动,当它接近底部时,然后触发一个函数,该函数只是将大数组中的下 50 条记录添加到我的表格数组中。这是从上面的链接到小提琴的直接链接。
HTML
HTML
<tbody when-scroll-ends="loadMoreRecords()">
<tr ng-repeat="row in tableData">
<td>{{row.attribute}}</td>
</tr>
</tbody>
Module
模块
angular.module(myApp, []).directive('whenScrollEnds', function () {
return {
restrict: "A",
link: function (scope, element, attrs) {
var processingScroll = false;
var visibleHeight = element.height();
var threshold = 200;
element.scroll(function () {
var scrollableHeight = element.prop('scrollHeight');
var hiddenContentHeight = scrollableHeight - visibleHeight;
if (hiddenContentHeight - element.scrollTop() <= threshold) {
// Scroll is almost at the bottom. Loading more rows
scope.$apply(attrs.whenScrollEnds);
}
});
}
};
});
Controller
控制器
function loadTableData() {
LoadDataService().getData().then(function(response) {
fullTableList = response.data;
$scope.tableData = fullTableList.slice(0,50);
});
}
function loadMoreRecords() {
// if there's still more than 20 records left, add the next chunk of 20
if (fullTableList.length - $scope.tableData.length > 20) {
$scope.tableData = $scope.tableData.concat(fullTableList.slice($scope.tableData.length,$scope.tableData.length + 20));
} else {
while ($scope.tableData.length < fullTableList.length) {
$scope.tableData.push(fullTableList[$scope.tableData.length]);
}
}
}