Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Speeding up Angular $compile function

I'm manually compiling a template against a new scope:

var scope = _.assign($rootScope.$new(true), {
  foo: 1,
  bar: 2
})
var element = angular.element('<my-element foo="foo" bar="bar"></my-element>')
$compile(element)(scope)
element.appendTo(container)

After running a basic profile, the slowest part of this code is $compile, which takes ~1ms per compilation. I need to compile ~100 elements at a time, as the user scrolls.

There are a lot of optimizations I can apply to speed up compilations after the 1st round of $compiles, but I'd like to speed up the very 1st round of 100 compiles. I'd also like to keep the templates in Angularland, and avoid injecting raw HTML.

How?

Edit: Copy+pasting my comment from below here for visibility for anyone that sees this thread in the future:

Ok, it finally makes sense. If you pass in a function as a 2nd argument to $link, angular will clone the node for you. If you don't, it will reuse the same node on every call to $link. Either way, you can access the returned node both synchronously (as the return value of $link) and asynchronously (within your callback). This is a poorly designed API, I filed an issue in Angular's issue tracker here - github.com/angular/angular.js/issues/11824

like image 308
bcherny Avatar asked Jan 09 '23 11:01

bcherny


1 Answers

If the elements are of the same structure and only differ in the scope against which they are linked, then you should $compile the template once and then link each of the 100 elements against their respective scopes.

var myElement = angular.element('<my-element foo="foo" bar="bar"></my-element>');
var myElementLinkFn = $compile(myElement);


// "items" here is the data that drives the creation of myElement elements
angular.forEach(items, function(item){
   var newScope = $scope.$new(true);

   newScope.foo = item.foo;
   newScope.bar = item.bar;

   myElementLinkFn(newScope, function(clone){
      container.append(clone);
   })
});
like image 55
New Dev Avatar answered Jan 19 '23 08:01

New Dev