Otimizar o carregamento de scripts de terceiros no Next.js

Entender a visão por trás do componente Script do Next.js, que oferece uma solução integrada para otimizar o carregamento de scripts de terceiros.

Leena sohoni
Leena Sohoni

Cerca de 45% das solicitações de sites veiculados em dispositivos móveis e computadores são solicitações de terceiros, e 33% são scripts. O tamanho, a latência e o carregamento de scripts de terceiros podem afetar significativamente o desempenho de um site. O componente Next.js Script vem com práticas recomendadas e padrões integrados para ajudar os desenvolvedores a introduzir scripts de terceiros nos aplicativos enquanto resolve possíveis problemas de desempenho prontos para uso.

Scripts de terceiros e o impacto deles no desempenho

Os scripts de terceiros permitem que os desenvolvedores da Web aproveitem as soluções atuais para implementar recursos comuns e reduzir o tempo de desenvolvimento. Mas os criadores desses scripts normalmente não têm qualquer incentivo para considerar o impacto do desempenho no site consumido. Esses scripts também são uma barreira para os desenvolvedores que os usam.

Os scripts são responsáveis por um número significativo de bytes de terceiros transferidos por download por sites em diferentes categorias de solicitações de terceiros. Por padrão, o navegador prioriza os scripts com base no local em que estão no documento, o que pode atrasar a descoberta ou a execução de scripts críticos para a experiência do usuário.

As bibliotecas de terceiros necessárias para o layout precisam ser carregadas antecipadamente para renderizar a página. Terceiros que não são necessários para a renderização inicial precisam ser adiados para não bloquear outros processamentos na linha de execução principal. O Lighthouse tem duas auditorias para sinalizar scripts de bloqueio de renderização ou de bloqueio de linhas de execução principais.

O Lighthouse faz as auditorias para eliminar os recursos que bloqueiam a renderização e minimizar o uso de terceiros

É importante considerar a sequência de carregamento de recursos da sua página para que os recursos críticos não atrasem e os não críticos não bloqueiem recursos críticos.

Embora existam práticas recomendadas para reduzir o impacto de terceiros, nem todo mundo sabe como implementá-las em todos os terceiros que usam. Isso pode ser complicado porque:

  • Em média, os sites usam 21 a 23 terceiros diferentes, incluindo scripts, em dispositivos móveis e computadores. O uso e as recomendações podem variar para cada opção.
  • A implementação de vários terceiros pode ser diferente dependendo do uso de uma determinada estrutura ou biblioteca de interface.
  • Bibliotecas de terceiros mais recentes são introduzidas com frequência.
  • Requisitos de negócios variados relacionados ao mesmo terceiro dificultam a padronização do uso pelos desenvolvedores.

O foco da Aurora em scripts de terceiros

Parte da colaboração da Aurora com frameworks e ferramentas da Web de código aberto é fornecer padrões sólidos e ferramentas opinativas para ajudar os desenvolvedores a melhorar aspectos da experiência do usuário, como desempenho, acessibilidade, segurança e prontidão para dispositivos móveis. Em 2021, nosso foco foi ajudar pilhas de frameworks a melhorar a experiência do usuário e as métricas das Core Web Vitals.

Uma das etapas mais importantes para alcançar nossa meta de melhorar o desempenho do framework envolveu pesquisar a sequência de carregamento ideal de scripts de terceiros no Next.js. Frameworks como o Next.js estão em uma posição única para fornecer padrões e recursos úteis que ajudam os desenvolvedores a carregar recursos com eficiência, incluindo terceiros. Analisamos vários dados do HTTP Archive e do Lighthouse para descobrir quais terceiros bloqueiam a renderização com mais frequência em diferentes frameworks.

Para resolver o problema do bloqueio de scripts de terceiros pela linha de execução principal em um aplicativo, criamos o componente de script. O componente encapsula os recursos de sequenciamento para oferecer aos desenvolvedores melhores controles para o carregamento de scripts de terceiros.

Sequenciamento de scripts de terceiros sem um componente de framework

As orientações disponíveis para reduzir o impacto dos scripts de bloqueio de renderização oferecem os seguintes métodos para carregar e sequenciar scripts de terceiros com eficiência:

  1. Use o atributo async ou defer com tags <script> que instruem o navegador a carregar scripts de terceiros não essenciais sem bloquear o analisador de documentos. Os scripts não necessários para o carregamento inicial da página ou a primeira interação do usuário podem ser considerados não críticos.

       <script src="https://example.com/script1.js" defer></script>
       <script src="https://example.com/script2.js" async></script>
    
  2. Estabeleça conexões antecipadas para as origens necessárias usando a pré-conexão e a pré-busca de DNS. Isso permite que scripts críticos iniciem o download mais cedo.

       <head>
           <link rel="preconnect" href="http://PreconnThis.com">
           <link rel="dns-prefetch" href="http://PrefetchThis.com">
       </head>
    
  3. Faça o carregamento lento de recursos e incorporações de terceiros após o carregamento do conteúdo da página principal ou quando o usuário rolar para baixo até a parte da página em que ele está incluído.

O componente Next.js Script

O componente Next.js Script implementa os métodos acima para sequenciar scripts e fornece um modelo para que os desenvolvedores definam a estratégia de carregamento. Depois que a estratégia adequada for especificada, ela vai carregar de forma otimizada sem bloquear outros recursos críticos.

O componente Script é baseado na tag HTML <script> e fornece uma opção para definir a prioridade de carregamento de scripts de terceiros usando o atributo de estratégia.

// Example for beforeInteractive:
<Script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver" strategy="beforeInteractive" />

// Example for afterInteractive (default):
<Script src="https://example.com/samplescript.js" />

// Example for lazyonload:
<Script src="https://connect.facebook.net/en_US/sdk.js" strategy="lazyOnload" />

O atributo estratégia pode aceitar três valores.

  1. beforeInteractive: essa opção pode ser usada para scripts essenciais que precisam ser executados antes que a página se torne interativa. O Next.js garante que esses scripts sejam injetados no HTML inicial no servidor e executados antes de outro JavaScript autoagrupado. O gerenciamento de consentimento, os scripts de detecção de bots ou as bibliotecas auxiliares necessárias para renderizar conteúdo essencial são bons candidatos para essa estratégia.

  2. afterInteractive: é a estratégia padrão aplicada e é equivalente a carregar um script com o atributo "adiar". Ela deve ser usada para scripts que o navegador pode executar depois que a página ficar interativa, por exemplo, scripts de análise. O Next.js injeta esses scripts no lado do cliente e eles são executados depois que a página é hidratada. Assim, a menos que especificado de outra forma, todos os scripts de terceiros definidos com o componente Script são adiados pelo Next.js, proporcionando um padrão forte.

  3. lazyOnload: essa opção pode ser usada para carregar lentamente scripts de baixa prioridade quando o navegador está inativo. A funcionalidade fornecida por esses scripts não é necessária imediatamente após a página se tornar interativa, por exemplo, chat ou plug-ins de mídia social.

Os desenvolvedores podem informar ao Next.js como seu aplicativo usa um script especificando a estratégia. Isso permite que o framework aplique otimizações e práticas recomendadas para carregar o script e, ao mesmo tempo, garantir a melhor sequência de carregamento.

Ao usar o componente Script, os desenvolvedores podem inserir um script de terceiros em qualquer lugar do aplicativo para o carregamento atrasado de terceiros e no nível do documento para scripts críticos. Isso implica que o componente Script pode ser colocado junto ao componente que usa o script. Depois da hidratação, o script é injetado na cabeça do documento inicialmente renderizado ou na parte inferior do corpo, dependendo da estratégia usada.

Como medir o impacto

Usamos os modelos do app de comércio e do blog para iniciantes do Next.js para criar dois apps de demonstração que ajudam a medir o impacto da inclusão de scripts de terceiros. Terceiros usados com frequência para o Gerenciador de tags do Google e incorporações de mídias sociais eram incluídos diretamente nas páginas desses apps e depois pelo componente Script. Depois, comparamos o desempenho dessas páginas no WebPageTest.

Scripts de terceiros em um app de comércio Next.js

Scripts de terceiros foram adicionados ao modelo do app de comércio para a demonstração, conforme mostrado abaixo.

.
Antes Depois
Gerenciador de tags do Google com recursos Componente de script com estratégia = afterInteractive para os dois scripts
Botão "Seguir" do Twitter sem "assíncrono" ou "adiar"
Configuração do script e do componente Script para a Demonstração 1 com dois scripts

A comparação a seguir mostra o progresso visual das duas versões do Next.js commerce starter-kit. Como aprendemos, a LCP ocorre quase um segundo antes, com o componente Script ativado com a estratégia de carregamento correta.

Comparação de tiras de filme mostrando melhorias em LCP

Scripts de terceiros em um blog do Next.js

Scripts de terceiros foram adicionados ao app do blog de demonstração, conforme mostrado abaixo.

.
Antes Depois
Gerenciador de tags do Google com recursos Componente de script com estratégia = Lazyonload para cada um dos quatro scripts
Botão "Seguir" do Twitter com "async"
Botão "Inscrever-se" do YouTube sem "assinar" ou "adiar"
Botão "Seguir" do LinkedIn sem "assíncrono" ou "adiar"
Configuração do script e do componente Script para a Demonstração 2 com quatro scripts
Vídeo mostrando o progresso de carregamento da página de índice com e sem o componente &quot;Script&quot;. Há uma melhoria de 0,5 segundo na FCP com o componente Script.

Como mostrado no vídeo, a primeira exibição de conteúdo (FCP, na sigla em inglês) ocorre a 0,9 segundo na página sem o componente "Script", e a 0,4 segundo com o componente "Script".

Próximas etapas do componente Script

Embora as opções de estratégia para afterInteractive e lazyOnload forneçam controle significativo sobre os scripts de bloqueio de renderização, também estamos explorando outras opções que aumentariam a utilidade do componente Script.

Como usar workers da web

Os Web workers podem ser usados para executar scripts independentes em linhas de execução em segundo plano, o que pode liberar a linha de execução principal para processar tarefas da interface do usuário e melhorar o desempenho. Os Web Workers são mais adequados para descarregar o processamento em JavaScript, em vez de trabalho de interface, fora da linha de execução principal. Scripts usados para suporte ao cliente ou marketing, que normalmente não interagem com a interface do usuário, podem ser bons candidatos para execução em uma linha de execução em segundo plano. Uma biblioteca leve de terceiros, a PartyTown, pode ser usada para isolar esses scripts em um worker da Web.

Com a implementação atual do componente de script Next.js, recomendamos adiar esses scripts na linha de execução principal definindo a estratégia como afterInteractive ou lazyOnload. No futuro, propomos a introdução de uma nova opção de estratégia, 'worker', que permitirá ao Next.js usar o PartyTown ou uma solução personalizada para executar scripts em workers da Web. Comentários de desenvolvedores sobre esse RFC são bem-vindos.

Como minimizar a CLS

Incorporações de terceiros, como anúncios, vídeos ou feeds de mídias sociais, podem causar mudanças de layout quando são carregadas lentamente. Isso afeta a experiência do usuário e a métrica Mudança de layout cumulativa (CLS) da página. A CLS pode ser minimizada especificando o tamanho do contêiner em que a incorporação será carregada.

O componente Script pode ser usado para carregar incorporações que podem causar mudanças de layout. Estamos pensando em aumentá-la para oferecer opções de configuração que ajudem a reduzir a CLS. Ele pode ser disponibilizado no próprio componente de script ou como um componente complementar.

Componentes do wrapper

A estratégia de sintaxe e carregamento para incluir scripts de terceiros conhecidos, como o Google Analytics ou o Gerenciador de tags do Google (GTM), geralmente é fixa. Eles podem ser encapsulados ainda mais em componentes de wrapper individuais para cada tipo de script. Apenas um conjunto mínimo de atributos específicos do aplicativo (como o ID de acompanhamento) estará disponível para os desenvolvedores. Os componentes do wrapper ajudam os desenvolvedores a:

  1. Facilitar a inclusão de tags de script populares.
  2. Garantir que o framework use a estratégia ideal em segundo plano.

Conclusão

Scripts de terceiros geralmente são criados para incluir recursos específicos no site consumidor. Para reduzir o impacto de scripts não essenciais, recomendamos adiá-los, o que é feito pelo componente Next.js Script. Os desenvolvedores têm a garantia de que scripts incluídos não vão atrasar funcionalidades essenciais, a menos que apliquem explicitamente a estratégia beforeInteractive. Assim como o componente Next.js Script, os desenvolvedores de frameworks também podem considerar a criação desses recursos em outras estruturas. Estamos explorando ativamente um componente semelhante com a equipe do Nuxt.js. Com base no feedback, esperamos aprimorar ainda mais o componente de script para abranger outros casos de uso.

Agradecimentos

Agradecemos a Kara Erickson, Janicklas Ralph, Katie Hempenius, Philip Walton, Jeremy Wagner e Addy Osmani pelo feedback sobre esta postagem.