DMurta
DMurta

Reputation: 315

angular ng-repeat as static content (performance issue)

I'm using a nested ng-repeat inside a <tbody> to generate a table with dynamic content (the table's content is sent by the backend and is unpredictable)

Since this table is already inside a directive that uses a ng-repeat by it's own, if I want to cause any changes, I can just request a new table with a new id.

the problem is, when this table is about 1000 lines long, or if I have multiple tables loaded in the interface, everything get's laggy.

For test purposes, I created the table html like:

for(var line = 0; line < $scope.content.tableBody.length; line++){
    testTable += "<tr>"
    for(var cell = 0; cell < $scope.content.tableHead.length; cell++){
        testTable += "<td style='background-color: WHITE'>"
        testTable += $scope.content.tableBody[line][$scope.content.tableHead[cell]].value
        testTable += "</td>"
    }
    testTable += "</tr>"
}

and used ng-bind-html to show it. The performance difference was huge. Of course I don't want to loose all the ease that angular provides in between (like ng-class, ng-style, ng-if), but it seems like all the scopes generated by ng-repeat causes a performance hit. I tried to use one binding ::, track by $index and so on, but without success.

Is it possible to use ng-repeat and, after everything is loaded, just make it's content 'static'? (withour scope, $watcher etc)

Upvotes: 1

Views: 426

Answers (1)

DMurta
DMurta

Reputation: 315

After trying to solve my problem with some tweaks in ng-repeat with one-time binding and track by $index, the solution that I found was to concatenate a string resulting in a tbody with the same logic that I previously used inside 2 nested ng-repeats. I then 'embed' this string inside my html using a directive that I found in another post.

delph.directive('compile', ['$compile', function ($compile) {
return function(scope, element, attrs) {
    var listener = scope.$watch(
        function(scope) {
            // watch the 'compile' expression for changes
            return scope.$eval(attrs.compile);
        },
        function(value) {
            // when the 'compile' expression changes
            // assign it into the current DOM
            element.html(value);

            // compile the new DOM and link it to the current
            // scope.
            // NOTE: we only compile .childNodes so that
            // we don't get into infinite loop compiling ourselves
            $compile(element.contents())(scope);

        }
    );


};
}]);

Memory consumption had a MAJOR improvement

Upvotes: 1

Related Questions