Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS app freezes when loading in new data to $scope

This is probably a difficult question to answer as I'm not sure what the root problem is here, would appreciate if someone would take a look though.

http://threadfinder.net/search%3FnameTags=jacket/0

If you continually scroll down, more items are loaded in using ngInfiniteScroll and this function:

$scope.moreProducts = function() {
        if ($scope.busy || $scope.noMore){return;}
        else 
        if (!($scope.busy)) {
            $scope.busy = true;
            $scope.itemsLoaded += 27;
            var theQuery = $routeParams.query.replace(/\?|%3f/gi, '');
            $scope.itemSearch.get({
                query: theQuery,
                page: $scope.itemsLoaded
            }, function(data) {
                if (data.posts.length <= 0) {
                    $scope.noMore = true;
                } else {
                    $scope.noMore = false;
                    for (var i = 0; i < data.posts.length; i++) {
                        if ($scope.user) {
                            if (!($scope.user.likes.indexOf(data.posts[i]._id) === -1)) {
                                data.posts[i].liked = 'http://i.imgur.com/CcqoATE.png';
                            } else {
                                data.posts[i].liked = 'http://i.imgur.com/tEf77In.png';
                            }
                            $scope.posts.push(data.posts[i]);
                        }
                    }
                    $scope.busy = false;
                }
            });
        }
    }

(I'm using AngularJS Deckgrid for the tile layout, but I've tried disabling it and there is no big change in performance.)

If you keep scrolling, after you get to ~300 items loaded on the page performance starts to take a hit and the app freezes while new items are being loaded into scope.

I understand that perhaps it's just a fact that loading in all this data takes a big load on the page - with every 27 items loaded in (one infiniteScroll GET call) the total weight of the data being loaded in is about 30kb a pop, so at around 300 items there's ~900kb of data in scope. This data is as little as I can make it (~500 lines of JSON).

The question is:

Are there any recommendations, plugins, directives or best-use practices for AngularJS for when loading a lot of data in the page $scope?

For clarification, the app is built on Node/ExpressJS/MongoDB

EDIT: I've checked out this issue on two computers (both on OSX) and this issue is MUCH more prevalent in Chrome than in Safari. Chrome totally staggers when loading in the data, Safari is really smooth and only has any noticable lag when you get to 600+ items and even then it's nowhere near as bad as Chrome.

like image 572
JVG Avatar asked Dec 08 '13 06:12

JVG


1 Answers

I took a look at the page with AngularJS Batarang, and it doesn't appear that your app is spending a lot of time in the digest cycle. If you take a look at Chrome's "Timeline" panel during the periods of UI lag, you can see the following:

Timeline

(full size)

Most of the time is spent in lots of "Parse HTML." A quick Google searched turned up this Stack Overflow question, which has some answers that may be useful; in particular, the Groups post about manual string concatenation by be worth trying here. You may also consider trying to break up the big block of HTML parses into smaller chunks by adding new items to the scope in small batches (perhaps using $evalAsync or a few timers) to see if that helps.

like image 189
Michelle Tilley Avatar answered Sep 27 '22 21:09

Michelle Tilley