Saltar al contenido
< samuelsantana.dev />
Volver al Blog

O Renascimento do Angular: Dominando Signals e a Nova Abordagem HTTP

Estás leyendo la versión en portugués de este artículo. Léelo en Español

Samuel Santana
Publicado el 07 de julho de 2026(Editado el 25 de julho de 2026)
AngularPerformance

Se você acompanha o ecossistema Angular de perto, sabe que o framework está passando pelo seu maior renascimento desde a reescrita do AngularJS para o Angular 2. Com a chegada das versões 16 e 17, e a consolidação nas versões mais recentes (18 a 21), o Google mudou as regras do jogo.

O foco agora é claro: Developer Experience (DX), performance extrema e a redução drástica de boilerplate. E no centro dessa revolução estão duas peças fundamentais: os Signals e a modernização do HttpClient.

Neste artigo, vamos dissecar como essas ferramentas mudam a forma como arquitetamos aplicações escaláveis.

🚦 O que são Signals e por que você deveria se importar?

Durante anos, o Angular confiou no Zone.js para detectar mudanças. O problema? O Zone.js é uma "marreta". Ele intercepta eventos assíncronos (cliques, timeouts, requisições HTTP) e, na dúvida, verifica a árvore de componentes inteira para ver se algo mudou. Em aplicações complexas, como plataformas SaaS multi-tenant com painéis de dados densos, isso gera gargalos de performance.

Os Signals trazem a reatividade de grão fino (fine-grained reactivity). Um Signal é um wrapper ao redor de um valor que notifica os consumidores apenas quando esse valor realmente muda. O framework passa a saber exatamente qual nó do DOM precisa ser atualizado, sem depender do Zone.js.

Os 3 Pilares dos Signals:
  1. signal(): O estado mutável básico.
  2. computed(): Estado derivado puro. Ele só é recalculado se os Signals dos quais depende mudarem, e o valor é guardado em cache (memoizado).
  3. effect(): Efeitos colaterais (como manipular o DOM diretamente ou salvar no localStorage) que rodam automaticamente quando suas dependências mudam.

Exemplo prático de uso:

import { Component, signal, computed, effect } from '@angular/core';

@Component({
  selector: 'app-cart',
  standalone: true,
  template: `
    <div>
      <p>Quantidade: {{ quantity() }}</p>
      <p>Preço Total: {{ totalPrice() | currency }}</p>
      <button (click)="increment()">Adicionar Item</button>
    </div>
  `
})
export class CartComponent {
  // Estado básico
  quantity = signal(1);
  unitPrice = 50.00;

  // Estado derivado (só recalcula quando quantity mudar)
  totalPrice = computed(() => this.quantity() * this.unitPrice);

  constructor() {
    // Efeito colateral focado em observabilidade ou debug
    effect(() => {
      console.log(`O valor do carrinho mudou para: ${this.totalPrice()}`);
    });
  }

  increment() {
    this.quantity.update(q => q + 1);
  }
}
Casos de Uso e Vantagens
  • Vantagem Absoluta: Previsibilidade e performance. O fim do famigerado erro ExpressionChangedAfterItHasBeenCheckedError.
  • Casos de Uso: Gerenciamento de estado local complexo, formulários dinâmicos e interfaces de alta interatividade (como dashboards em tempo real).

🌐 A Nova Abordagem HTTP: Adeus Módulos, Olá Fetch API

Junto com a reatividade, a forma como o Angular lida com injeção de dependências e requisições de rede evoluiu. O antigo HttpClientModule está sendo deixado para trás na era dos Standalone Components.

A partir do Angular 15 (e consolidado como padrão no 17+), a recomendação é utilizar o provideHttpClient(). Mais do que uma mudança de sintaxe, essa nova API trouxe o withFetch().

O poder do withFetch()

Historicamente, o HttpClient usava a API XMLHttpRequest por baixo dos panos. Ao habilitar o withFetch(), o Angular passa a usar a Fetch API nativa dos navegadores modernos. Isso não apenas melhora a performance e reduz o tamanho do bundle, mas é um requisito vital se você está utilizando Server-Side Rendering (SSR) ou Static Site Generation (SSG), pois o Node.js lida muito melhor com o fetch nativo.

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withFetch } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withFetch()) // Simples, limpo e performático
  ]
};

🌉 Unindo os Dois Mundos: RxJS vs Signals

A pergunta que todo recrutador técnico ou Tech Lead faz hoje é: "Os Signals vão matar o RxJS?"

A resposta de um engenheiro sênior é: Não. Eles resolvem problemas diferentes.

O RxJS é excepcional para lidar com eventos assíncronos ao longo do tempo (como debouncing de inputs ou WebSockets). Já os Signals são perfeitos para estado síncrono. A beleza do Angular moderno está na interoperabilidade. Com o pacote @angular/core/rxjs-interop, podemos fazer requisições HTTP (que retornam Observables) e transformá-las em Signals de forma elegante com o toSignal:

import { Component, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { toSignal } from '@angular/core/rxjs-interop';

@Component({
  selector: 'app-user-profile',
  standalone: true,
  template: `
    @if (user()) {
      <h1>{{ user().name }}</h1>
    } @else {
      <p>Carregando...</p>
    }
  `
})
export class UserProfileComponent {
  private http = inject(HttpClient);
  
  // Transforma o Observable da requisição HTTP diretamente em um Signal
  user = toSignal(this.http.get<User>('/api/user/1'));
}

Nota: A nova sintaxe de Control Flow (@if, @for) do Angular 17+ combina perfeitamente com Signals.

Conclusão

A engenharia de software é sobre adotar os padrões corretos para resolver gargalos de escala. A migração mental para os Signals e o uso do novo HttpClient com Fetch API não são apenas "hype". São ferramentas tangíveis que reduzem a carga cognitiva do desenvolvedor, diminuem o tamanho da aplicação e entregam um produto final visivelmente mais rápido para o usuário. O Angular não está apenas acompanhando o mercado; ele está ditando uma nova forma de arquitetar o frontend.

Comentarios

Cargando comentarios...