Angularjs performance issue (not $digest-related)

1,550 views
Skip to first unread message

Paolo Milani Comparetti

unread,
Sep 26, 2013, 6:36:20 PM9/26/13
to ang...@googlegroups.com
Hi,

I am experiencing a performance issue with angularjs. Most of the advice out there for angular performance is related to the $digest cycle and dirty checking. This is not the problem I have, the page is responsive once loaded. The problem I have is on loading the page, or when switching routes.

I found one question on stack overflow which I think is from someone encountering a similar problem: http://stackoverflow.com/questions/17656397/angular-js-scaling-performance, but none of the answers or comments are helpful for cases where the $digest cycle is fast enough already.

Basically, each view of my single-page app displays an arbitrary sequence of widgets, as specified by a piece of json. This is an ng-repeat wrapping an ng-switch. Here is a simplified view, where the configuration has been loaded into the widgets scope variable:

<div ng-view>
  <div ng-repeat="widget in widgets">
    <div ng-switch on="widget.name">
      <div ng-switch-when="foo">
         <foo opts="widget.opts"></foo>
      </div>
      <div ng-switch-when="bar">
         <bar opts="widget.opts"></bar>
      </div>
    </div>
</div>

In my app there are about 15 different branches to the ng-switch, and a single page displays up to maybe 8 of them so far. The actual page is a bit more complex as the page is divided into a top, bottom, and center with two columns, each of which has an ng-repeat like the one above. Each widget can be somewhat complex, but the page works fairly fast. it is only on first load or when switching back and forth between routes that everything freezes for as long as 15 seconds.

I tried using batarang (which has helped me in the past) to profile this, but the profiling functionality it offers seems to be focused on the $digest cycle. The chrome developer tools, OTOH, show that on a route change (when the set of widgets to display changes) the bulk of the time is spent first parsing HTML and then garbage collecting. Parsing HTML seems to mean assigning to a DOM element's innerHTML, which happens inside jquery.

I am wondering if anyone has any pointers on how to figure out what the performance bottleneck is, or how I might fix it. Also, I wonder if the approach I am using to display arbitary combinations of widgets (ng-repeat+ng-switch) has intrinsically limited scalability, and if I should use an alternative approach. For instance, I could have a custom compile function that generates the template corresponding to a specific configuration of widgets (only once at runtime for each configuration), and get rid of the ng-repeat+ng-switch completely.

thanks in advance,
Paolo Milani

Paolo Milani Comparetti

unread,
Oct 1, 2013, 6:11:24 PM10/1/13
to ang...@googlegroups.com
Hi,


I am wondering if anyone has any pointers on how to figure out what the performance bottleneck is, or how I might fix it. Also, I wonder if the approach I am using to display arbitary combinations of widgets (ng-repeat+ng-switch) has intrinsically limited scalability, and if I should use an alternative approach. For instance, I could have a custom compile function that generates the template corresponding to a specific configuration of widgets (only once at runtime for each configuration), and get rid of the ng-repeat+ng-switch completely.

seems no-one had any pointers, but I found a solution, which indeed involved getting rid of the ng-repeat + ng-switch.

I now have a service which, given a configuration (list of widgets to show where on the page) generates a template for that particular configuration (doing some basic string concatenation to generate an html template with exactly that set of widgets). Then it $compiles the template and caches the result.

The container directive takes the name of the configuration as an attribute, loads the compiled the template and links it.

Switching routes (and widget configurations) is now essentially instant (apart from AJAX calls).

This seems like another interesting example of where one may need to compromise on the more anuglar way of doing things for performance (concatenating strings in the template instead of letting angular do that). But I think it speaks to the strength of the framework that this was doable in a fairly clean way in about 1 day of implementation.

ciao
Paolo
Reply all
Reply to author
Forward
0 new messages