Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DOM manipulation done in compile phase runs once, and propagate always - what this means

I'm reading this article about angular performance optimization and there is the following passage there:

Directive's compile functions run before scope is attached and are the perfect place to run any DOM manipulations (binding events for example). The important thing to recognize from a performance point of view, is that the element and attributes passed into the compile function represent the raw html template, before any of angular's changes have been made. What this means in practice is that DOM manipulation done here, will run once, and propagate always. Another important point that is frequently glossed over is the difference between prelink and postlink. In short, prelinks run from the outside in, while postlinks run from the inside out. As such, prelinks offer a slight performance boost, as they prevent the inner directives from running a second digest cycle when the parent modifies scope in the prelink. However, child DOM may not yet be available.

I can't understand these two parts and how I can use it to boost performance:

What this means in practice is that DOM manipulation done here, will run once, and propagate always.

And this

prelinks offer a slight performance boost, as they prevent the inner directives from running a second digest cycle when the parent modifies scope in the prelink

I'd appreciate if anyone could elobarate on that.

like image 372
Max Koretskyi Avatar asked Apr 03 '15 17:04

Max Koretskyi


1 Answers

What this means in practice is that DOM manipulation done here, will run once, and propagate always.

Run Once?

This is referring to the AngularJS compilation process. As the AngularJS compiler traverses the DOM, it will compile the directives that it finds exactly once.

DOM Manipulation?

When a directive's compile function is called, there is an opportunity to modify the HTML ahead of the AngularJS compiler.

Propagate Always?

This just means that the final DOM is determined at the end of the compilation process.

Example

To hit the point home, consider the following example:

<div directive1> <!-- grandparent -->
    <div directive2>  <!-- parent -->
         <div directive3> <!-- child -->
         </div>
    </div>
</div>

The AngularJS compiler will visit the grandparent first, then the parent, and finally the child.

There are three opportunities to modify the HTML ahead of angular compilation:

  1. directive1 compile function
  2. directive2 compile function
  3. directive3 compile function

Now consider how the final HTML changes when we manipulate the DOM in the compile function for directive1:

When the directive1's compile function is called:

<div directive1> <!-- compiled -->
    <div directive2>  <!-- not compiled -->
         <div directive3> <!-- not compiled -->
         </div>
    </div>
</div>

In the compile function, let's change the HTML ahead of the AngularJS compiler:

app.directive('directive1', function() {
     restrict: 'A',
     compile: function($element, $attr) {
         // $element points to directive1 element
         $element.html('<div directive4></div>');
     }
});

After the compile function for directive1 is called:

<div directive1> <!-- compiled -->
    <div directive4>  <!-- not compiled -->
    </div>
</div>

Notice how the DOM changes so that directive2 and directive3 no longer exist and directive4 is next in line to be compiled.

prelinks offer a slight performance boost, as they prevent the inner directives from running a second digest cycle when the parent modifies scope in the prelink

Hmm. This makes no sense to me. As I understand it, the digest phase happens after the pre-link and post-link phases. I'm not sure how modifying scope in pre-link or post-link phases will impact the digest cycle.

The following image has been referenced from this article: http://www.toptal.com/angular-js/angular-js-demystifying-directives

enter image description here

like image 76
pixelbits Avatar answered Oct 20 '22 04:10

pixelbits