IE11 slow / freeze with AngularJS's ng-repeat rendering

前端 未结 2 701
我在风中等你
我在风中等你 2020-12-10 04:40

Currently I have a very sublte problem to solve with IE11 and AngularJS.

My page consists of two nested ng-repeat to create a tabset with a table inside any tab.

相关标签:
2条回答
  • 2020-12-10 05:13

    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.

    I ended up following this link to 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 fiddle from the link above.

    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]);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-10 05:16

    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:

    • 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)
    0 讨论(0)
提交回复
热议问题