Detecção de mudanças
Todo componente tem um detector de mudanças responsável por checar os vínculos definidos em seu template. Exemplos de vínculos: `` e [todo]="t"
. Detectores de mudança propaga vínculos[c] da raiz para as folhas em uma busca em profundidade.
Por padrão a detecção de mudança ocorre por todo nó da árvore para verificar o que foi mudado, e o que fazer a cada evento do navegador. Embora isto pareça terrivelmente ineficiente, o sistema de detecção de mudanças do Angular 2 pode percorrer milhares de checagens simples (números são dependentes da plataforma) em poucos milissegundos.
Objetos imutáveis
Se um componente depender somente de seus vínculos, e seus vínculos são imutáveis, então o componente pode mudar, e somente mudar, se um de seus vínculos mudar. Portanto, podemos cortar a detecção de mudança nas subárvores de um componente até que um evento ocorra. Quando isto acontece, podemos checar a subárvore apenas uma única vez, e então, desabilitar até a próxima mudança (caixas em cinza indicam os detectores desabilitados)
Para implementar isto basta configurar a estratégia de detecção de mudança para ON_PUSH
@Component({changeDetection:ON_PUSH})
class ImmutableTodoCmp {
todo:Todo;
}
Objetos Observáveis
Se o componente depende apenas de seus vínculos, e os vínculos são observáveis, então este componente pode mudar se, e somente se, um de seus vínculos emitir um evento. Portanto, podemos cortar a detecção de mudanças na subárvore do componente até que um evento ocorra. Quando isto acontece, podemos checar a subárvore apenas uma única vez, e então desabilitá-la até a próxima mudança.
NOTA: Se você tem uma árvore de componentes com vínculos imutáveis, uma mudança tem que passar por todos os componentes desde a raiz. Este não é o caso quando tratamos com observáveis
type ObservableTodo = Observable<Todo>;
type ObservableTodos = Observable<Array<ObservableTodo>>;
@Component({selector:’todos’})
class ObservableTodosCmp {
todos:ObservableTodos;
//...
}
<todo *ng-for=”var t of todos” todo=”t”></todo>
@Component({selector:'todo'})
class ObservableTodoCmp {
todo:ObservableTodo;
//...
}
Digamos que a aplicação usa somente objetos observáveis. Quando ele inicia, Angular irá checar todos os objetos.
Após o primeiro passo irá parece com o seguinte:
Digamos que o primeiro observável todo dispara um evento. O sistema irá mudar para o seguinte estado:
E depois de checar App_ChangeDetector
, Todos_ChangeDetector
, e o primeiro Todo_ChangeDetector
, irá voltar para este estado.
Assumindo que as mudanças ocorrem raramente e os componentes formam uma árvore balanceada, usando mudanças observáveis a complexidade de detecção de mudanças vai de O(N)
para O(logN)
, onde N é o número de vínculos em um sistema.
LEMBRE-SE
- Uma aplicação Angular 2 é um sistema reativo.
- O sistema de detecção propaga dos vínculos da raiz as folhas.
- Diferente do Angular 1.X, o Grafo de detecção de mudanças é uma árvore direcionada. Como resultado, o sistema é mais performático e previsível.
- Por padrão, o sistema de detecção de mudanças percorre toda a árvore. Mas se você usa objetos imutáveis ou observáveis, você pode tomar a vantagem deles e apenas checar partes da árvore que “realmente mudam”.
- Estas otimizações compõem e não quebram as garantias que o detector de mudanças provê.