The playground

More information here

UX Mais suave na carga de páginas com resolvedores angulares

como um desenvolvedor, você está sempre procurando otimizar o seu código. Isto inclui a velocidade a que você apresenta o usuário com a UI totalmente carregada, que é muitas vezes dependente de dados provenientes de uma base de dados.inevitavelmente, você começa a procurar formas de resolver os dados imediatamente após a navegação para uma nova […]

como um desenvolvedor, você está sempre procurando otimizar o seu código. Isto inclui a velocidade a que você apresenta o usuário com a UI totalmente carregada, que é muitas vezes dependente de dados provenientes de uma base de dados.inevitavelmente, você começa a procurar formas de resolver os dados imediatamente após a navegação para uma nova página / área de sua aplicação, sem que o usuário encontre o que é conhecido como page JANK.

isto é quando a página se move para cima e para baixo enquanto carrega certos componentes. Pode afectar significativamente o UX até ao ponto em que parece “buggy”.

Angular fornece uma abordagem intuitiva à pré-obtenção de dados antes das cargas de rota; antes que a rota navegada se resolva.

é chamado de resolvedor Angular.

um resolvedor Angular é essencialmente um serviço Angular. Uma classe injetável que você fornece para um módulo de roteamento na configuração de rota. Este tipo especial de serviço é injectado e executado quando a rota que contém é navegada para.

o resolvedor resolve então os dados antes da carga da página, que se torna disponível através do serviço ActivatedRoute. Isso fornece uma maneira simples e eficiente de garantir que o usuário tenha os dados o mais rápido possível antes que um componente que é importante para a carga inicial da página precisasse deles.

outra maneira de usar um resolvedor Angular é usando – o como um método para povoar os metadados SEO instantaneamente.

com um resolvedor, você está fornecendo uma garantia de que os dados existirão antes da Página ter carregado, garantindo que tudo tem o que precisa na inicialização.

Vamos desagregação Angular de Resolução

Uma resolução Angular é uma classe que implementa Resolve interface. A interface Resolve requer que você implemente uma função dentro da classe chamada resolve.

Aqui está a Resolver interface assinatura…

export interface Resolve<T> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<T> | Promise<T> | T {
return 'data';
}
}

Como podemos ver a partir da interface de assinatura, requer um argumento genérico T qual será o tipo do nosso resolvido de dados.

A resolver função retorna um ObservablePromise ou apenas os dados do tipo T . Portanto, há uma sugestão de que isso deve ser tratado assíncronamente, especialmente se recuperar os dados da base de dados.

O principal propósito da função resolver é que ela tem que completar. Este fato precisa ser lembrado ao recuperar dados em observáveis. O observável deve estar completo. Afinal de contas, é um resolver.

Se o observável não estiver completo, então os dados nunca serão resolvidos, e a Página nunca será carregada. Portanto, você precisa definir o ponto em que você não precisa tomar mais os valores e os dados podem resolver, como você tem tudo que você precisa a partir do banco de dados. Ao usar fluxos de dados assíncronos como observables, este é um caso de uso para operadores pipeable de RXJS.

os operadores pipeable que vêm à mente ao pensar em completar um fluxo de dados baseado em uma condição, é uma combinação de filtertakefirst . Com esta combinação, você pode filtrar todos os valores que você não deseja tomar, como null ou undefined ou uma matriz vazia , então take o primeiro valor válido com take(1).

operadores que podem ser necessários para completar um observável cedo ao encontrar problemas ou erros, em que você vai querer retornar null ou redirecionar, são catchError e timeout . Uma combinação de timeout e catchError é útil se os dados que está a demorar demasiado tempo e você gostaria de voltar null para que você possa tentar novamente dentro do componente, ou se você deseja redirecionar.

Se os seus dados não se resolverem rapidamente, é baseado em filtragem complexa, lógica, enormes quantidades de chamadas de banco de dados, é provável que você experimente problemas de vez em quando.

é melhor determinar a menor quantidade de chamadas de banco de dados, e dados mínimos que são necessários para carregar com sucesso e graciosamente a página.

consequentemente, você pode se beneficiar de passar algum tempo, antes de implementar o seu resolvedor, para se concentrar em separar o Conteúdo ‘acima da dobra’ dos dados que podem ser carregados quando a página inicializa.

portanto, você pode dividir os dados necessários para um UX suave, a partir do resto dos dados que poderiam ser chamados a partir do componente, em vez do resolvedor.

Você pode então lidar exclusivamente com o conteúdo mínimo, acima da dobra, através do resolvedor.

Esta abordagem dinâmica à carga de páginas pode ser assistida com o uso de esqueletos. De modo que se o Usuário se desloca instantaneamente, você pode dar ao usuário a indicação de que o conteúdo está carregando, posteriormente melhorando UX.

Passo 1: Criando o resolvedor

precisamos criar o resolvedor Angular. No entanto, não existe um comando Angular CLI que gera um resolvedor. Portanto, teremos que escrever o decorador (metadados resolver) nós mesmos.

felizmente, são apenas algumas linhas de código que formam o boilerplate para um resolvedor, e nós podemos tomar o decorador injetável de um serviço existente se você está lutando para lembrá-lo.

anotar a classe de resolução do perfil com um decorador injetável

primeiro, nós fornecemos o decorador injetável com providedIn: any na configuração.

@Injectable({ providedIn: 'any'})

iremos então nomear o nosso resolvedor adicionando a ConvençãoResolver. Para este exemplo, vamos estar resolvendo dados de perfil (dados de usuário), então vamos chamá-lo ProfileResolver .

Como é um resolvedor, e Angular reconhece a função dos resolvers, podemos implementar a classe Resolve, que irá fornecer a assinatura que temos de implementar em nossa função de resolução para resolver com sucesso os dados.

@Injectable({providedIn: 'any'})
export class ProfileResolver implements Resolve<Profile> {
}

a nossa função de resolução irá devolver um observável com dados conformes com a interfaceProfile. Portanto, vamos fornecer a interface Profile como o argumento genérico para a classe resolver e a função resolve(). Desta forma, conformámo-nos com os requisitos angulares para um resolvedor.

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<T> | Promise<T> | T {
return;
}

A resolver implementação nos dá dois parâmetros, se necessário, route e state . Estes são povoados automaticamente e são acessíveis a partir de dentro da nossa função resolve().

em seguida, precisamos realmente resolver dados reais a partir do banco de dados, que será o nosso próximo passo.recuperando os dados da base de dados

para recuperar os dados para a nossa função de resolução, teremos de injectar o serviço que fornece os dados; um que interage com a base de dados.

tiramos o que precisamos dele para resolver rapidamente para que o usuário navegue com prontidão e sucesso. Para os propósitos desta demo, não nos preocuparemos com o serviço subjacente que lida com o banco de dados. Vamos apenas injectar o serviço usando a injeção de dependência no argumento do construtor para a nossa classe ProfileResolver.

Como nossos dados vem na forma de um Observável fluxo de dados com valores múltiplos emissores de forma assíncrona, nós só precisamos take(1) usando o pipeable operador take importada a partir de rxjs/operator . Caso contrário, o observável nunca terminaria, e o resolver nunca…se resolveria.

só precisamos de uma emissão / valor e take completa o observável para nós.

é tão simples quanto isso para criar um resolvedor; nós só precisamos retornar o observável noresolve() função que angular irá lidar com a assinatura de.

The ProfileResolver Class

we handle any errors in retrieving the data by redirecting to a parent route.bónus: Popularize metadados dinâmicos SEO rapidamente antes que a rota tenha carregado

os benefícios de popularizar o nosso<meta> tags instantaneamente tem benefícios óbvios. Quanto mais rápido forem os metadados do SEO, mais rápido o nosso SEO reflete corretamente e com precisão o conteúdo da página.isto significa que é mais fácil e mais rápido para os robôs, tais como aqueles operados por motores de busca como Google e Bing, rastejarem pelo seu site e recuperarem o conteúdo.

isto não é tão importante nas páginas pré-renderizadas ou aquelas que são renderizadas por Universal Angular, Porque toda a renderização está completa antes que os robôs recebam o conteúdo.

no Entanto, se você depender de (muitas vezes questionáveis) capacidade para que os robôs do google para analisar o javascript para o SEO, ou você tem uma demanda solução como marionetista que precisa da garantia de que o SEO será correto antes de retornar a prestação do DOM, em seguida, uma resolução que inclui SEO deve ajudar. Então ajuda quando o rastejante é limitado no tempo.

também separa preocupações do componente, de modo que o componente não tem que lidar com nada relacionado com SEO. Uma das principais razões pelas quais eu gosto de resolvers.

Passo 2: injetar o resolvedor no módulo de encaminhamento

o ProfileRoutingModule onde estaremos fornecendo ao nosso resolvedor um módulo carregado preguiçoso. Portanto, nosso caminho de raiz estará vazio com o parâmetro token userSlug , que precisaremos para recuperar os dados de perfil corretos.

para fornecer o nosso resolvedor, nós apenas fornecemos um objeto com o nome de nossos dados como a chave e o resolvedor específico como o valor que será responsável por resolver esses dados.

Você pode nomear a chave o que quiser, mas nós vamos apenas chamá-lo de dados.

Nossa ProfileRoutingModule

isso é tudo que é necessário o módulo de roteamento para que possamos usar a nossa resolução.em seguida, precisamos recuperar e usar nossos dados no componente.

Passo 3: Inicializar o componente com dados resolvidos

Agora que resolvemos os nossos dados na activação da rota, os dados são acessíveis através do serviço ActivatedRoute. Como estamos lidando com observáveis, ao longo da aplicação, vamos criar um fluxo que se liga à propriedade data que será nossos dados resolvidos.

Primeiro, vamos injectar o ActivatedRouteno construtor do nossoProfileComponent. Em seguida, atribuiremos this.route.data ao profile$ observável. Também vamos querer mudar para usar um observável quando os dados atualizados chegam da base de dados para que tenhamos novos dados quando estamos interagindo com o aplicativo.

Para isso, vamos usar startWith assim que começamos a nossa corrente com o valor que é facilmente acessível a partir de this.route.snapshot.data. Nós então acessamos a propriedade data propriedade como this.route.snapshot.datastartWith indica um valor para começar, como a primeira emissão do nosso fluxo.

Nosso Perfil do Componente

o Que imediatamente acessível de dados para o componente

Imediatamente acessível de dados, reduzindo o tempo de carregamento de cada uma das peças dessa página, o que é observado pelo usuário. O resultado de não usar um resolvedor como este é que a página pode parecer carregar de uma forma fragmentada, o que não é visualmente agradável.

consequentemente, você terá que prestar atenção a quais elementos dos seus modelos HTML são dependentes de que dados. Você deve então escrever o seu resolver para suportar estes elementos e o efeito geral sobre o carregamento de páginas UX.

Existem várias maneiras que o componente pode carregar fragmentada

  • Uma delas é se você tiver um ngIf em várias partes do seu modelo HTML.
  • outro é ngFor.

é a melhor prática limitar a quantidade individual ngIf ‘s que escreve para limitar a quantidade de redimensionamento que o navegador tem de fazer.

carregar a página antes de obter os dados pode fazer com que partes da sua página saltem, se atrasem e redimensionem constantemente, fazendo com que o UX sofra.

implementar um resolvedor pode ser a diferença entre o usuário experimentando 3-5 segundos de salto e redimensionamento vs. 0.5 segundos, que é muitas vezes muito rápido para ser prejudicial para o UX geral.é isso! Temos um resolver com um UX melhorado na carga de página.

Deixe uma resposta

O seu endereço de email não será publicado.