Otimizar o carregamento de scripts de terceiros no Next.js

Entenda 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 Script Next.js vem com práticas recomendadas integradas e padrões para ajudar os desenvolvedores a inserir scripts de terceiros nos aplicativos e resolver 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 Web aproveitem as soluções atuais para implementar recursos comuns e reduzir o tempo de desenvolvimento. No entanto, os criadores desses scripts normalmente não têm nenhum incentivo para considerar o impacto no desempenho do site que consome. Esses scripts também são uma caixa preta para os desenvolvedores que os utilizam.

Os scripts representam um número significativo de bytes de terceiros baixados por sites em diferentes categorias de solicitações de terceiros. Por padrão, o navegador prioriza scripts com base no local em que eles estão no documento, o que pode atrasar a descoberta ou a execução de scripts essenciais para a experiência do usuário.

As bibliotecas de terceiros necessárias para o layout precisam ser carregadas com antecedência para renderizar a página. Terceiros que não são necessários para a renderização inicial precisam ser adiados para que não bloqueiem 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 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 estejam atrasados 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 pode estar ciente de como implementá-las para 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 ser diferentes para cada um deles.
  • A implementação de vários serviços terceirizados pode ser diferente dependendo do uso de um framework ou biblioteca de interface específico.
  • Bibliotecas de terceiros mais recentes são introduzidas com frequência.
  • Vários requisitos de negócios relacionados ao mesmo terceiro dificultam a padronização do uso pelos desenvolvedores.

Foco da Aurora em scripts de terceiros

Parte da colaboração da Aurora com frameworks e ferramentas de código aberto da Web é fornecer padrões fortes 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 as pilhas de framework a melhorar a experiência do usuário e as 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. Estruturas como o Next.js estão posicionadas de maneira exclusiva para fornecer padrões e recursos úteis que ajudam os desenvolvedores a carregar recursos com eficiência, incluindo terceiros. Estudamos diversos dados do HTTP Archive e do Lighthouse para descobrir quais terceiros bloqueiam a renderização em diferentes frameworks.

Para resolver o problema do bloqueio de scripts de terceiros na linha de execução principal usados em um aplicativo, criamos o componente Script. O componente encapsula os recursos de sequência para oferecer aos desenvolvedores controles melhores para o carregamento de scripts de terceiros.

Sequenciamento de scripts de terceiros sem um componente do framework

A orientação disponível para reduzir o impacto dos scripts de bloqueio de renderização fornece 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 informam ao navegador para carregar scripts de terceiros não críticos sem bloquear o analisador de documentos. 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 iniciais com as origens necessárias usando a pré-conexão e a pré-busca de DNS. Isso permite que os scripts críticos comecem a ser baixados mais cedo.

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

O componente Next.js Script

O componente Script Next.js implementa os métodos acima para sequenciar scripts e fornece um modelo para que os desenvolvedores definam a estratégia de carregamento. Uma vez definida a estratégia adequada, ela é carregada de maneira ideal, sem bloquear outros recursos críticos.

O componente Script se baseia na tag <script> do HTML 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 de estratégia aceita três valores.

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

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

  3. lazyOnload: essa opção pode ser usada para carregar scripts de baixa prioridade lentamente 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, plug-ins de chat ou mídia social.

Os desenvolvedores podem informar a Next.js como o 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, garante a melhor sequência de carregamento.

Com o componente Script, os desenvolvedores podem colocar um script de terceiros em qualquer lugar do aplicativo para que terceiros de carregamento tardiamente e no nível do documento para scripts críticos. Isso significa que o componente Script pode ser colocado no componente que usa o script. Após a hidratação, o script será injetado no cabeçalho do documento inicialmente renderizado ou na parte inferior do corpo, dependendo da estratégia usada.

Como medir o impacto

Usamos os modelos do app comercial Next.js e do blog inicial (links em inglês) para criar dois apps de demonstração que ajudaram 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 foram incluídos diretamente nas páginas desses apps e depois pelo componente Script. Em seguida, comparamos o desempenho dessas páginas no WebPageTest.

Scripts de terceiros em um app comercial da Next.js

Scripts de terceiros foram adicionados ao modelo de app comercial para a demonstração, conforme mostrado abaixo.

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

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

Comparação de tiras de filme mostrando melhorias na 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 async Componente de script com estratégia = Slowonload para cada um dos quatro scripts
Botão "Seguir" do Twitter com assíncrono
Botão "Inscrever-se" do YouTube sem sincronização ou adiamento
Botão "Seguir" do LinkedIn sem sincronização ou adiamento
Configuração dos componentes de script e script para a Demonstração 2 com 4 scripts.
Vídeo mostrando o progresso do carregamento da página de índice com e sem o componente Script. Há uma melhoria de 0,5 segundo na FCP com o componente Script.

Como mostrado no vídeo, a First Contentful Paint (FCP) ocorre em 0,9 segundo na página sem o componente Script e 0,4 segundo com o componente Script.

O que vem a seguir para o componente Script

Embora as opções de estratégia para afterInteractive e lazyOnload forneçam um controle significativo sobre scripts de bloqueio de renderização, também estamos explorando outras opções para aumentar 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 JavaScript, em vez de trabalho de interface, para fora da linha de execução principal. Os scripts usados para marketing ou suporte ao cliente, que normalmente não interagem com a interface, podem ser bons candidatos para execução em uma linha de execução em segundo plano. Uma biblioteca leve de terceiros, PartyTown, pode ser usada para isolar esses scripts em um web worker.

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á que a Next.js use a PartyTown ou uma solução personalizada para executar scripts em web workers. Aceitamos comentários de desenvolvedores neste RFC.

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 Cumulative Layout Shift (CLS, na sigla em inglês) 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. Isso pode ser disponibilizado no próprio componente Script ou como um componente complementar.

Componentes do wrapper

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

  1. Facilitando a inclusão de tags de script conhecidas.
  2. Garantir que o framework use a melhor estratégia nos bastidores.

Conclusão

Scripts de terceiros são geralmente criados para incluir recursos específicos no site de consumo. Para reduzir o impacto de scripts não críticos, recomendamos adiá-los, o que o componente Next.js Script faz por padrão. Os desenvolvedores têm a garantia de que os scripts incluídos não atrasarão funcionalidades essenciais, a menos que eles apliquem explicitamente a estratégia beforeInteractive. Assim como o componente Script Next.js, os desenvolvedores de framework também podem considerar a criação desses recursos em outras estruturas. Estamos buscando ativamente um componente semelhante com a equipe do Nuxt.js. Com base no feedback, também esperamos melhorar ainda mais o componente 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.