Como Funciona o Change Detection do Angular por Baixo dos Panos
Você já parou para pensar em como o Angular sabe exatamente o momento de atualizar a tela quando o valor de uma variável muda? No JavaScript puro, precisaríamos manipular o DOM manualmente. No Angular, isso acontece de forma quase mágica graças ao Change Detection (Detecção de Mudanças).
Compreender como esse mecanismo funciona não é apenas preciosismo técnico: é o segredo para evitar problemas de performance e bugar o ciclo de renderização da sua aplicação.
O que é o Change Detection?
O Change Detection é o processo pelo qual o Angular projeta o estado atual dos dados da sua aplicação na interface do usuário (DOM). Sempre que um evento acontece, o Angular varre os componentes para verificar se o modelo de dados (o código TypeScript) mudou e, se sim, atualiza a View (o HTML).
Historicamente, o Angular dependia de uma biblioteca chamada Zone.js. Ela envelopava operações assíncronas do navegador (como cliques, requisições HTTP e temporizadores) para avisar o Angular: “Ei, algo aconteceu, rode a detecção de mudanças!”.
Nota moderna: Atualmente, o Angular está evoluindo para um modelo Zoneless (sem Zone.js) usando Signals, o que torna essa detecção incrivelmente mais cirúrgica e performática.
A Árvore de Componentes
Uma aplicação Angular é uma árvore de componentes. Quando a detecção de mudanças é disparada, por padrão, o Angular começa do componente raiz (AppComponent) e vai descendo, checando cada um dos componentes de cima para baixo.
Essa checagem é unidirecional e extremamente rápida, mas em aplicações gigantescas com milhares de componentes, checar tudo o tempo todo pode se tornar um gargalo. É aqui que entram as estratégias de detecção.
Estratégias de Change Detection: Default vs. OnPush
O Angular nos dá duas formas de configurar como um componente deve se comportar:
1. Estratégia Default (CheckAlways)
Se você não especificar nada, essa é a estratégia padrão. O componente será verificado a cada ciclo de detecção de mudanças, não importa de onde o evento surgiu. Se o botão de um componente X for clicado, o componente Y do outro lado da tela será reavaliado mesmo que seus dados não tenham mudado.
2. Estratégia OnPush
Ao mudar para OnPush, você está dizendo ao Angular: “Só verifique este componente se eu explicitamente mandar, ou se as propriedades de entrada (@Input()) mudarem de referência”.
Para ativar, basta configurar no decorator do seu componente:
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-card-usuario',
templateUrl: './card-usuario.component.html',
changeDetection: ChangeDetectionStrategy.OnPush // <--- Aqui
})
export class CardUsuarioComponent {
@Input() usuario!: { nome: string };
}
A Pegadinha da Mutabilidade com OnPush
Se você usa OnPush, precisa entender o conceito de imutabilidade. O Angular checa apenas a referência do objeto passado no @Input().
Se você fizer isso no componente pai:
// Isso NÃO dispara o Change Detection no componente filho OnPush
this.usuario.nome = 'Alex';
A propriedade interna mudou, mas a referência do objeto usuario na memória continua a mesma. O Angular vai ignorar o componente filho.
Para funcionar corretamente com OnPush, você deve passar uma nova referência:
// Isso DISPARA o Change Detection (Criou um novo objeto na memória)
this.usuario = { ...this.usuario, nome: 'Alex' };
Resumo: Quando usar cada uma?
-
Use
Default: Em formulários complexos locais, componentes muito simples ou telas pequenas onde a performance não é uma preocupação e os dados mudam de forma muito dinâmica. -
Use
OnPush: Na grande maioria dos componentes de apresentação, listas grandes, tabelas e componentes que recebem dados de seletores do NgRx/Signals. É a melhor prática para arquiteturas escaláveis.
Conclusão
O mecanismo de Change Detection do Angular é poderoso e inteligente, mas dá ao desenvolvedor o controle total para otimizar o fluxo de renderização. Ao dominar a estratégia OnPush e conceitos de imutabilidade (ou adotando os novos Signals), você garante que sua aplicação frontend rode a 60 quadros por segundo, sem travamentos desnecessários.