使用AngularJS的ng-repeat渲染缓慢/冻结IE11

时间:2015-05-25 18:20:27

标签: javascript angularjs internet-explorer browser

目前我有一个非常明显的问题需要解决IE11和AngularJS。

我的页面由两个嵌套的ng-repeat组成,用于创建一个带有任何标签内表格的标签集。

此处代码为:http://pastebin.com/0fffPz5Z

在代码中,每个应用程序的对象都有大约1.000个项目的相关对象。 使用Chrome,Safari和Mozilla我没有问题,一切都是超高速的!使用IE11,页面变慢,IE11向我显示一个太慢的页面脚本的消息....

我用这个结果创建了IE11界面的分析: https://www.dropbox.com/s/y5xuystxht6gjkr/IE11-interface-profiling.png?dl=0

这是另一个IE11的错误???对不起我的英文,并提前感谢任何建议。

编辑:目前(为了“调试”目的)我删除了所有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>

2 个答案:

答案 0 :(得分:19)

AngularJs对每页渲染绑定有限制(在某些文章中,您可以发现它大约是2000个绑定)。目前你刚刚面临这种情况。 chrome和Mozilla顺利运行的原因是它们的DOM操作得到了更好的优化。 为了提高您的表现,请尝试:

  • 避免在ng-repeat中使用sort(在插入前对其进行排序)
  • 使用一次性绑定(:: syntax)
  • 删除不必要的手表
  • 优化摘要周期
  • 使用分页
  • 用ReactJs组件替换angularjs ng-repeat(如果数据量非常大)

答案 1 :(得分:3)

刚遇到同样的问题。如果一切都在Chrome上完美运行,那么在IE中进行测试,它会随着超过1000条记录而崩溃。

我最后跟随this link添加了一个&#34;延迟加载&#34;或者&#34;无限滚动&#34;到我的桌子。因此,在表加载时,它仍然会提取所有1000多条记录,但是不是将这些数据直接加载到表中,而是将其加载到一个大数组中,然后只将我的50个记录表作为子集。然后创建一个监听表格滚动的指令,当它接近底部时,然后触发一个函数,该函数只是将大数组中接下来的50条记录添加到我的表格数组中。这是以上链接中的直接link to the fiddle

<强> HTML

<tbody when-scroll-ends="loadMoreRecords()">
    <tr ng-repeat="row in tableData">
        <td>{{row.attribute}}</td>
    </tr>
</tbody>

<强>模块

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);
                }
            });
        }
    };
});

<强>控制器

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]);
        }
    }
}