<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Paulo Lôbo</title>
    <description>The latest articles on Forem by Paulo Lôbo (@paulo_loboneto_80163ca4e).</description>
    <link>https://forem.com/paulo_loboneto_80163ca4e</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1358556%2F49b33a5b-ef36-47b1-9463-f2cea0193a20.jpeg</url>
      <title>Forem: Paulo Lôbo</title>
      <link>https://forem.com/paulo_loboneto_80163ca4e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/paulo_loboneto_80163ca4e"/>
    <language>en</language>
    <item>
      <title>Lamba LLRT(Low Latency Runtime Javascript)</title>
      <dc:creator>Paulo Lôbo</dc:creator>
      <pubDate>Tue, 20 Aug 2024 12:42:53 +0000</pubDate>
      <link>https://forem.com/paulo_loboneto_80163ca4e/lamba-llrt-elb</link>
      <guid>https://forem.com/paulo_loboneto_80163ca4e/lamba-llrt-elb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Aviso: todo e qualquer conteúdo postado é com objetivo de relembrar ou manter os meus conhecimentos e espero que possa te ajudar na sua caminhada pelo aprendizado também.&lt;br&gt;
Esse post é vivo e será atualizado periodicamente. &lt;br&gt;
Caso você encontre alguma falha ou perceba que falta algo, me ajude a melhorar :)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Você já parou para pensar que estamos sendo cada vez mais exigidos em relação à performance das nossas aplicações? A cada dia, somos desafiados a torná-las mais rápidas, e, com isso, somos levados a avaliar soluções e arquiteturas que nos possibilitem alcançar esse resultado.&lt;/p&gt;




&lt;p&gt;Portanto a ideia é trazer um post curto, informando sobre uma nova evolução que pode nos ajudar a ter um aumento &lt;strong&gt;considerável&lt;/strong&gt; de performance em aplicações serverless no AWS Lambda. Essa solução é o &lt;strong&gt;LLRT Javascript&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;LLRT Javascript(Low Latency Runtime Javascript)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Um novo runtime JavaScript está sendo desenvolvido pela equipe da AWS. No momento, ele é experimental, e há esforços para lançar uma versão estável até o final de 2024&lt;/p&gt;

&lt;p&gt;veja a &lt;a href="https://github.com/awslabs/llrt" rel="noopener noreferrer"&gt;descrição&lt;/a&gt; que a AWS apresenta:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;LLRT (Low Latency Runtime) is a lightweight JavaScript runtime designed to address the growing demand for fast and efficient Serverless applications. LLRT offers up to over 10x faster startup and up to 2x overall lower cost compared to other JavaScript runtimes running on AWS Lambda&lt;br&gt;
It's built in Rust, utilizing QuickJS as JavaScript engine, ensuring efficient memory usage and swift startup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Veja que eles pretendem entregar algo até 10x mais rápido do que outros runtimes JS.&lt;/p&gt;

&lt;p&gt;Toda essa construção é feita utilizando o &lt;a href="https://www.rust-lang.org/pt-BR" rel="noopener noreferrer"&gt;Rust&lt;/a&gt;, que é uma linguagem com alto poder de desempenho e o &lt;a href="https://bellard.org/quickjs/" rel="noopener noreferrer"&gt;QuickJS&lt;/a&gt;, que é um motor de JavaScript leve e de alto desempenho, projetado para ser pequeno, eficiente e compatível com a especificação &lt;a href="https://tc39.es/ecma262/#sec-intro" rel="noopener noreferrer"&gt;ECMAScript&lt;/a&gt; mais recente, incluindo recursos modernos como classes, async/await, e módulos. Além disso, é utilizada uma abordagem que não usa JIT. Com isso, ao invés de alocar recursos para compilação Just-In-Time, conserva esses recursos para a execução de tarefas do próprio código.&lt;/p&gt;

&lt;p&gt;Mas calma que nem tudo são flores, são tradeoffs(trocadilho horrível, eu sei rsrs). &lt;br&gt;
Portanto, há alguns pontos importantes para se avaliar antes de pensar em adotar o LLRT JS. Veja o que a AWS informa:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are many cases where LLRT shows notable performance drawbacks compared with JIT-powered runtimes, such as large data processing, Monte Carlo simulations or performing tasks with hundreds of thousands or millions of iterations. LLRT is most effective when applied to smaller Serverless functions dedicated to tasks such as data transformation, real time processing, AWS service integrations, authorization, validation etc. It is designed to complement existing components rather than serve as a comprehensive replacement for everything. Notably, given its supported APIs are based on Node.js specification, transitioning back to alternative solutions requires minimal code adjustments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Além disso, a &lt;a href="https://github.com/awslabs/llrt?tab=readme-ov-file#compatibility-matrix" rel="noopener noreferrer"&gt;ideia&lt;/a&gt; é que o LLRT JS não seja um substituto para o node.js e nem nunca será.&lt;/p&gt;

&lt;p&gt;Veja:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;LLRT only support a fraction of the Node.js APIs. It is NOT a drop in replacement for Node.js, nor will it ever be. Below is a high level overview of partially supported APIs and modules. For more details consult the API documentation.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Testes Avaliativos
&lt;/h2&gt;

&lt;p&gt;Levando em consideração a aplicabilidade que foi citada pela própria AWS, vamos realizar dois testes para avaliar e comparar o LLRT com o NodeJS. Um dos testes será para o cálculo de números primos e o outro para uma chamada simples de API.&lt;/p&gt;

&lt;p&gt;Porque utilizar o cálculo de números primos?&lt;br&gt;
A resposta é que o alto processamento requerido para identificar números primos resulta da necessidade de realizar muitas operações matemáticas(divisões) para verificar a primalidade, da distribuição imprevisível dos primos, e da complexidade crescente com o tamanho dos números. Esses fatores combinam-se para tornar a verificação de primalidade e a busca por números primos uma tarefa computacionalmente intensa, especialmente em grandes escalas.&lt;/p&gt;



&lt;p&gt;Mãos na massa então...&lt;/p&gt;

&lt;p&gt;Crie a primeira função lambda com nodejs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvgcbgblvdddc6xcsn117.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvgcbgblvdddc6xcsn117.png" alt="Image description" width="800" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora, vamos criar a função com o LLRT JS. Optei por utilizar a opção de &lt;a href="https://github.com/awslabs/llrt?tab=readme-ov-file#option-2-use-a-layer" rel="noopener noreferrer"&gt;layer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Crie a layer:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F81bags78jp64fodsnu2d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F81bags78jp64fodsnu2d.png" alt="Image description" width="800" height="742"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois crie a função:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa9hqjeen5azpllk33od.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa9hqjeen5azpllk33od.png" alt="Image description" width="800" height="664"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E adicione essa layer a função LLRT JS criada:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfcnce7aja0eu9ar2xki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfcnce7aja0eu9ar2xki.png" alt="Image description" width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para o teste de números primos, vamos usar o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let isLambdaWarm = false
export async function handler(event)  {

    const limit = event.limit || 100000;  // Defina um limite alto para aumentar a complexidade
    const primes = [];
    const startTime = Date.now()
    const isPrime = (num) =&amp;gt; {
        if (num &amp;lt;= 1) return false;
        if (num &amp;lt;= 3) return true;
        if (num % 2 === 0 || num % 3 === 0) return false;
        for (let i = 5; i * i &amp;lt;= num; i += 6) {
            if (num % i === 0 || num % (i + 2) === 0) return false;
        }
        return true;
    };

    for (let i = 2; i &amp;lt;= limit; i++) {
        if (isPrime(i)) {
            primes.push(i);
        }
    }

  const endTime = Date.now() - startTime

    const response = {
        statusCode: 200,
        body: JSON.stringify({
            executionTime: `${endTime} ms`,
            isLambdaWarm: `${isLambdaWarm}`
        }),
    };


    if (!isLambdaWarm) { 
        isLambdaWarm = true
    }

    return response;
};


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E para o teste de API, vamos usar o código abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let isLambdaWarm = false
export async function handler(event) {

  const url = event.url || 'https://jsonplaceholder.typicode.com/posts/1'
  console.log('starting fetch url', { url })
  const startTime = Date.now()

  let resp;
  try {
    const response = await fetch(url)
    const data = await response.json()
    const endTime = Date.now() - startTime
    resp = {
      statusCode: 200,
      body: JSON.stringify({
        executionTime: `${endTime} ms`,
        isLambdaWarm: `${isLambdaWarm}`
      }),
    }
  }
  catch (error) {
    resp = {
      statusCode: 500,
      body: JSON.stringify({
        message: 'Error fetching data',
        error: error.message,
      }),
    }
  }

  if (!isLambdaWarm) {
    isLambdaWarm = true
  }

  return resp;
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Resultados dos testes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O objetivo é mais educacional aqui, portanto nossa amostra para cada teste é constituído de 15 dados em warm start e 1 de cold start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consumo de memória&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LLRT JS - para ambos os testes, houve o consumo da mesma quantidade de memória: 23mb.&lt;/p&gt;

&lt;p&gt;NodeJS - para o teste de números primos, o nodejs começou consumindo 69mb e indo até 106mb. &lt;br&gt;
Já para o teste de API, o mínimo foi 86mb e o máximo com 106mb. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tempo de execução&lt;/strong&gt;&lt;br&gt;
após a remoção dos outliers, esse foi o resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5ucqd62n81caera3ad5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5ucqd62n81caera3ad5.png" alt="Image description" width="740" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftu2os980s7y7xy649ljj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftu2os980s7y7xy649ljj.png" alt="Image description" width="750" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relatório final&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consumo de memória - para o consumo de memória foi observado que o LLRT fez o melhor uso do recurso disponível se comparado ao nodejs.&lt;/p&gt;

&lt;p&gt;Performance - percebemos que no cenário de alto processamento, o node manteve uma performance bem superior ao LLRT, tanto no cold start quanto warm start.&lt;br&gt;
Para o cenário de menor processamento, o LLRT obteve uma certa vantagem, principalmente no cold start.&lt;/p&gt;

&lt;p&gt;Vamos, então, aguardar os resultados finais e esperar que possamos ter ainda mais melhorias significativas. Mas é muito bom ver a flexibilidade do JavaScript e perceber o quanto ele pode e ainda tem a nos oferecer.&lt;/p&gt;




&lt;p&gt;Espero que tenha gostado e que isso tenha ajudado a melhorar sua compreensão ou até mesmo aberto caminhos para novos conhecimentos. Conto com você para críticas e sugestões, para que possamos melhorar o conteúdo e mantê-lo sempre atualizado para a comunidade.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>awslambda</category>
      <category>node</category>
      <category>lamballrt</category>
    </item>
    <item>
      <title>Angular - Estratégias de roteamento e History API</title>
      <dc:creator>Paulo Lôbo</dc:creator>
      <pubDate>Thu, 15 Aug 2024 21:33:17 +0000</pubDate>
      <link>https://forem.com/paulo_loboneto_80163ca4e/angular-router-3h9g</link>
      <guid>https://forem.com/paulo_loboneto_80163ca4e/angular-router-3h9g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Aviso: todo e qualquer conteúdo postado é com objetivo de relembrar ou manter os meus conhecimentos e espero que possa te ajudar na sua caminhada pelo aprendizado também.&lt;br&gt;
Esse post é vivo e será atualizado periodicamente. &lt;br&gt;
Caso você encontre alguma falha ou perceba que falta algo, me ajude a melhorar :)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Veja um resumo do passo a passo que o angular faz para realizar o roteamento de uma aplicação:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Configuração de Rotas&lt;/strong&gt;: primeiro, você define as rotas no módulo de roteamento com &lt;code&gt;RouterModule.forRoot(routes)&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serviço Router&lt;/strong&gt;: depois, você utiliza os serviços do Router para realizar a navegação;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atualização da URL&lt;/strong&gt;: em seguida o angular atualiza a History API e também atualiza a url na barra de endereços do navegador, ou não(falo dele no final);&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Correspondência de Rotas&lt;/strong&gt;: O angular compara a URL com as rotas definidas e carrega o componente correspondente;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Renderização e Detecção de Mudanças&lt;/strong&gt;: Por fim, renderiza o componente e atualiza o DOM.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Tipos de estratégias&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Os frontends SPAs possuem 2 estratégias mais comuns de roteamento:&lt;br&gt;
HashLocationStrategy(Hash mode) e PathLocationStrategy(History mode).&lt;/p&gt;

&lt;p&gt;Para quem já trabalha com SPAs no dia-a-dia sabe bem a diferença mais básica das duas estratégias:&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;PathLocationStrategy (History Mode)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;As URLs seguem o padrão tradicional de navegação na web, sem nenhum #. Por exemplo:&lt;br&gt;
&lt;a href="https://paulo.com/home" rel="noopener noreferrer"&gt;https://paulo.com/home&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;HashLocationStrategy (Hash Mode):&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;As URLs incluem um # seguido do caminho. O que vem após o # não é enviado ao servidor e é tratado inteiramente pelo navegador.&lt;br&gt;
Exemplo de URL: &lt;a href="https://paulo.com/#/home" rel="noopener noreferrer"&gt;https://paulo.com/#/home&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;O PathLocationStrategy é a configuração default do angular, e caso deseje utilizar a estratégia de hash, precisará declarar assim no seu arquivo de rotas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RouterModule.forRoot(routes, {useHash: true})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Há alguns debates sobre o melhor uso de cada um. Alguns comentam sobre a estratégia de se utilizar o HashLocation somente em arquitetura SSR e outros que entendem que traz mais simplicidade e por isso o utilizam em todos os cenários, mas não vou entrar nesse detalhe. Fica a dica caso se interesse em procurar mais sobre a discussão&lt;/em&gt; :)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;History API&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Por baixo dos panos o angular usa a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API" rel="noopener noreferrer"&gt;History API&lt;/a&gt; para se comunicar com o roteamento do navegador.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular/blob/0bbbd784827f1ebc8c49ce3032a6f1b125bc1a57/packages/common/src/location/location_strategy.ts#L152C12-L152C21" rel="noopener noreferrer"&gt;Link para implementação da PathLocationStrategy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagem mostrando o acionamento do angular durante uma mudança de rota, usando estratégia de pathlocation:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jhgdubr4kg1rp6jrwhq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jhgdubr4kg1rp6jrwhq.png" alt="Imagem mostrando o acionamento do angular durante uma mudança de rota" width="800" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular/blob/0bbbd784827f1ebc8c49ce3032a6f1b125bc1a57/packages/common/src/location/hash_location_strategy.ts#L84" rel="noopener noreferrer"&gt;Link para implementação da HashLocationStrategy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagem mostrando o acionamento do angular durante uma mudança de rota, usando estratégia de hashlocation:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljq35t7ppy6ezxlh51fn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljq35t7ppy6ezxlh51fn.png" alt="Imagem mostrando o acionamento do angular durante uma mudança de rota" width="800" height="51"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;History&lt;/strong&gt; é uma interface/API do navegador que permite manipular o histórico de navegação do usuário sem recarregar a página. Ela foi introduzida com a especificação do HTML5 e oferece um conjunto de métodos para adicionar, modificar ou remover entradas do histórico do navegador, além de responder a mudanças no estado da navegação.&lt;/p&gt;

&lt;p&gt;Veja:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1t1q5xkqolyqcct3rpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1t1q5xkqolyqcct3rpn.png" alt="na imagem é mostrada a url localhost:4200 e no console do navegador é mostrado o tamanho do objeto history api, utilizando o history.length. O history.length possui o tamanho igual a 1" width="800" height="364"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00eoocpshbipfr4x698x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00eoocpshbipfr4x698x.png" alt="na imagem é mostrada a url localhost:4200/componentA e no console do navegador é mostrado o tamanho do objeto history api, utilizando o history.length. O history.length possui o tamanho igual a 2" width="800" height="412"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmtnu71gm67c6ctvelr3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmtnu71gm67c6ctvelr3.png" alt="na imagem é mostrada a url localhost:4200/componentB e no console do navegador é mostrado o tamanho do objeto history api, utilizando o history.length. O history.length possui o tamanho igual a 3" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;repare que a cada mudança de rota, o objeto "history" vai sendo incrementado. &lt;/p&gt;

&lt;p&gt;Tanto o location(&lt;em&gt;import { Location } from "@angular/common"&lt;/em&gt;), quanto o router(&lt;em&gt;import { Router } from "@angular/router"&lt;/em&gt;)acionam/comunicam com a History API&lt;/p&gt;

&lt;p&gt;Isso ocorre porque toda vez que navegamos para uma rota qualquer, o angular aciona o platformLocation, que por sua vez, aciona o método &lt;a href="https://github.com/angular/angular/blob/3b0dca75d6dab6039253edd00c436715775bd0dd/packages/common/src/location/platform_location.ts#L161" rel="noopener noreferrer"&gt;&lt;em&gt;history.pushState&lt;/em&gt;&lt;/a&gt;. Da mesma forma, o método history.replaceState é invocado toda vez que utilizamos o &lt;a href="https://github.com/angular/angular/blob/3b0dca75d6dab6039253edd00c436715775bd0dd/packages/common/src/location/platform_location.ts#L165" rel="noopener noreferrer"&gt;&lt;em&gt;replaceUrl&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Um ponto interessante é que o angular também atualiza o objeto &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Location" rel="noopener noreferrer"&gt;Location&lt;/a&gt;.&lt;br&gt;
O Location mantém todos os dados da rota durante a navegação.&lt;/p&gt;

&lt;p&gt;Repare, que ao usar o PathLocation, o objeto location mostra o pathname que correlaciona com a mesma rota na url do navegador:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg9uye9zgktp42z5goa1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg9uye9zgktp42z5goa1g.png" alt="a imagem mostra o console.log do location que correlaciona com a mesma rota na url do navegador" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Já ao usar o hashlocation, o pathname fica sempre vazio e somente o atributo "hash" é alterado:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhlzt0ip6usmbqtfyanek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhlzt0ip6usmbqtfyanek.png" alt="a imagem mostra o console.log do location que correlaciona com a mesma rota na url do navegador" width="800" height="350"&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Em breve solto um post sobre a importância na escolha das estratégias ao criar um app Server Side Rendering(&lt;a href="https://angular.dev/guide/ssr" rel="noopener noreferrer"&gt;https://angular.dev/guide/ssr&lt;/a&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Uma observação importante é que apesar da History API conseguir suprir as principais necessidades e servir para os frontends SPA’s mais atuais, a partir do momento que avançamos para alguns cenários, como a própria necessidade de se realizar a observabilidade de um SPA, notamos algumas debilidades nessa API. Para sanar esses problemas, uma nova proposta de substituição dessa API está em andamento, que é a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API" rel="noopener noreferrer"&gt;Navigation API&lt;/a&gt;. Ela ainda está em fase experimental e falaremos mais dela no post sobre monitoramento e performance de SPA.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;SkipLocationChange&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Lembra do que escrevi sobre o angular acionar o histórico.pushState? &lt;br&gt;
O que essa opção faz é garantir que o conteúdo seja renderizado na tela, mas dessa vez sem acionar o método &lt;em&gt;history.pushstate&lt;/em&gt; que é responsável por definir a URL do navegador. Só o status interno do Router que será atualizado. Nesse caso, o navegador não sabe que houve mudança no histórico.&lt;/p&gt;

&lt;p&gt;Vamos a um exemplo…&lt;br&gt;
Repare que,&lt;/p&gt;

&lt;p&gt;o history.state possui tamanho == 1&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwr9w28ytftru97ni0ou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwr9w28ytftru97ni0ou.png" alt="imagem mostrando o tamanho do objeto history.state" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E quando navego para uma próxima rota com o skipLocation ativo(&lt;code&gt;&lt;br&gt;
this.router.navigate(['componentA'], {skipLocationChange: true});&lt;br&gt;
&lt;/code&gt;), ele não altera a url e nem o estado da api de histórico&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80idxdzcet8tuinjp52p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80idxdzcet8tuinjp52p.png" alt="imagem mostrando o tamanho do objeto history.state" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;no entanto, quando acessamos os eventos que o router emite, é possível ver que o estado interno do Router está atualizado&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyz7daga8d0xyzk34h9an.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyz7daga8d0xyzk34h9an.png" alt="imagem mostrando o tamanho do objeto history.state e também mostrando o console.log do objeto activatedRoute" width="800" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dessa forma, somente o angular tem o estado mais atual e o navegador não possui a informação mais atualizada.&lt;/p&gt;




&lt;p&gt;Eu espero que tenha gostado e te ajudado a melhorar a compreensão de algo ou até mesmo aberto caminhos para novos conhecimentos. Conto com você nas críticas e sugestões para irmos melhorando o conteúdo e mantendo sempre atualizado para a comunidade. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>angular</category>
      <category>angularrouter</category>
    </item>
  </channel>
</rss>
