[Angular] Tirando proveito do Lazy Loading!

O Angular é mais uma ferramenta incrível para a criação de SPA, mas como todos nós sabemos uma conexão lenta pode deixar a experiência do usuário um tanto desagradável ao seu primeiro acesso, pois é nesse momento que ele vai baixar todo o bundle da aplicação (que às vezes fica bem pesadinho né).

Para suprir isso temos uma técnica bem conhecida, que é deixar sua SPA “preguiçosa” que na real acelera e muito seu carregamento! Lazy Loading basicamente é separar os módulos da sua aplicação de maneira que eles são carregados apenas quando são chamados (resolvendo aquele problema inicial, pois o carregamento da página será apenas de um módulo e não a aplicação inteira).

Fazer Lazy Loading em uma aplicação Angular é extremamente simples, basta fazer uma importação dinâmica do seu módulo no seu arquivo de roteamento através do atributo “loadChildren”.

RouterModule.forRoot([
  {
    path: 'clients',
    loadChildren: () => import('./clients/client.module').then(m => m.ClientModule)
  }
]);

Assim o Angular só vai carregar este módulo quando o usuário acessar esta rota, compilando seus componentes e exibindo-os.

É isso, simples, lindo e dá uma diferença gigantesca na sua SPA que não tem explicação! Mas calma lá, mesmo assim tem módulos que podem ser pesados também e a demora só é passada para frente, não seria sensacional se a gente pudesse carregar todos os outros módulos em background enquanto o usuário está navegando no módulo que acabou de carregar?

Podemos! E o mais legal de tudo, é super mega simples também!

Para isso precisamos precisamos dizer ao Angular qual será nossa estratégia de carregamento para os módulos, que são: Por demanda (só carrega quando for solicitada, padrão), tudo (carrega todos os módulos em background) ou uma customizada (dependendo da aplicação carregar tudo não faz muito sentido, criar sua própria estratégia “prevendo” o fluxo do usuário pode ser algo que faça mais sentido e deixe sua SPA mais leve ainda!).

Para ativar nossa estratégia de carregar tudo é muito simples.

import { RouterModule, PreloadAllModules } from '@angular/router';

RouterModule.forRoot([
  {
    path: 'clients',
    loadChildren: () => import('./clients/client.module').then(m => m.ClientModule)
  }
], { preloadingStrategy: PreloadAllModules });

Primeiro importamos nossa estratégia do Angular router e colocamos ele com na propriedade “preloadingStrategy” em um objeto após a definição de nossas rotas, passando sua estratégia. E é isso, agora quando você entrar na sua aplicação ela irá carregar o módulo inicial e quando acabar, em background, carregará os outros módulos.

Para criar suas próprias estratégias, você apenas precisa criar um serviço que implementa a interface “PreloadingStrategy” do Angular router, essa interface pedirá a criação do método “preload” que recebe a rota e uma função (que de fato realiza o preloading) e retorna um Observable.

export class CustomPreloadingStrategy implements PreloadingStrategy {
  preload(route: Route, load: Function): Observable<any> {
    // Code :)
  }
}

Com sua estratégia definida basta importá-la em seu módulo de rotas e atribuí-la ao seu preloadingStrategy. E é isso, que coisa maravilhosa.


Abraços!