Exibir códigos modernos em navegadores modernos para acelerar o carregamento de página

Criar sites que funcionem bem em todos os principais navegadores é um princípio fundamental de um ecossistema da Web aberto. No entanto, isso significa mais trabalho para garantir que todo o código criado tenha suporte em cada navegador que você planeja usar. Se você quer usar novos recursos de linguagem JavaScript, é necessário transpilá-los para formatos compatíveis com versões anteriores para navegadores que ainda não oferecem suporte a eles.

O Babel é a ferramenta mais usada para compilar código que contém sintaxe mais recente em código que diferentes navegadores e ambientes (como o Node) podem entender. Neste guia, pressupomos que você está usando o Babel. Portanto, siga as instruções de configuração para incluí-lo no aplicativo, caso ainda não tenha feito isso. Selecione webpack em Build Systems se você estiver usando o webpack como o bundler de módulo no app.

Para usar o Babel apenas para transpilação do que é necessário para seus usuários, é necessário:

  1. Identifique os navegadores que você quer segmentar.
  2. Use @babel/preset-env com os destinos de navegador adequados.
  3. Use <script type="module"> para interromper o envio de código transpilado para navegadores que não precisam dele.

Identifique os navegadores que você quer segmentar

Antes de começar a modificar como o código do aplicativo é transpilado, é necessário identificar quais navegadores acessam o aplicativo. Para tomar uma decisão fundamentada, analise quais navegadores seus usuários estão usando e aqueles que você planeja segmentar.

Usar @babel/preset-env

A transcompilação do código geralmente resulta em um arquivo maior em tamanho do que nas formas originais. Ao minimizar a quantidade de compilação, é possível reduzir o tamanho dos pacotes para melhorar o desempenho de uma página da Web.

Em vez de incluir plug-ins específicos para compilar seletivamente determinados recursos de linguagem que você está usando, o Babel fornece várias predefinições que agrupam plug-ins. Use @babel/preset-env para incluir apenas as transformações e polyfills necessárias para os navegadores que você planeja segmentar.

Inclua @babel/preset-env na matriz presets no arquivo de configurações do Babel, .babelrc:

{
 "presets": [
   [
     "@babel/preset-env",
     {
       "targets": ">0.25%"
     }
   ]
 ]
}

Use o campo targets para especificar quais versões do navegador você quer incluir adicionando uma consulta adequada ao campo browsers. O @babel/preset-env se integra à browserslist, uma configuração de código aberto compartilhada entre diferentes ferramentas para segmentação de navegadores. Há uma lista completa de consultas compatíveis na documentação do browserslist. Outra opção é usar um arquivo .browserslistrc para listar os ambientes que você quer segmentar.

O valor ">0.25%" instrui o Babel a incluir apenas as transformações necessárias para oferecer suporte a navegadores que compõem mais de 0,25% do uso global. Isso garante que o pacote não contenha código transpilado desnecessário para navegadores usados por uma porcentagem muito pequena de usuários.

Na maioria dos casos, essa é uma abordagem melhor do que usar a seguinte configuração:

  "targets": "last 2 versions"

O valor "last 2 versions" transcompila seu código para as duas últimas versões de cada navegador. Isso significa que o suporte é oferecido para navegadores descontinuados, como o Internet Explorer. Isso pode aumentar desnecessariamente o tamanho do seu pacote se você não espera que esses navegadores sejam usados para acessar seu aplicativo.

Por fim, selecione a combinação apropriada de consultas para segmentar apenas os navegadores que atendem às suas necessidades.

Ativar correções de bugs modernas

O @babel/preset-env agrupa vários recursos de sintaxe do JavaScript em coleções e os ativa/desativa com base nos navegadores de destino especificados. Embora isso funcione bem, uma coleção inteira de recursos de sintaxe é transformada quando um navegador de destino contém um bug com apenas um recurso. Isso muitas vezes resulta em mais código transformado do que o necessário.

Originalmente desenvolvido como uma predefinição separada, a opção de correções de bugs em @babel/preset-env resolve esse problema convertendo a sintaxe moderna que está corrompida em alguns navegadores para a sintaxe equivalente mais próxima que não está corrompida nesses navegadores. O resultado é um código moderno quase idêntico com alguns pequenos ajustes de sintaxe que garantem a compatibilidade em todos os navegadores de destino. Para usar essa otimização, verifique se o @babel/preset-env 7.10 ou mais recente está instalado e defina a propriedade bugfixes como true:

{
 "presets": [
   [
     "@babel/preset-env",
     {
       "bugfixes": true
     }
   ]
 ]
}

No Babel 8, a opção bugfixes será ativada por padrão.

Usar <script type="module">

Os módulos JavaScript, ou módulos ES, são um recurso relativamente novo com suporte em todos os principais navegadores. É possível usar módulos para criar scripts que podem importar e exportar de outros módulos, mas também é possível usá-los com @babel/preset-env para segmentar apenas os navegadores compatíveis com eles.

Em vez de consultar versões específicas do navegador ou participação de mercado, especifique "esmodules" : true dentro do campo targets do arquivo .babelrc.

{
   "presets":[
      [
         "@babel/preset-env",
         {
            "targets":{
               "esmodules": true
            }
         }
      ]
   ]
}

Muitos recursos ECMAScript mais recentes compilados com o Babel já têm suporte em ambientes com suporte a módulos JavaScript. Assim, você simplifica o processo de garantir que apenas o código transpilado seja usado para navegadores que realmente precisam dele.

Os navegadores que oferecem suporte a módulos ignoram scripts com um atributo nomodule. Por outro lado, os navegadores que não oferecem suporte a módulos ignoram elementos de script com type="module". Isso significa que você pode incluir um módulo e um substituto compilado.

O ideal é que os dois scripts de versão de um aplicativo sejam incluídos assim:

  <script type="module" src="main.mjs"></script>
  <script nomodule src="compiled.js" defer></script>

Os navegadores que oferecem suporte a módulos buscam e executam main.mjs e ignoram compiled.js. Os navegadores que não são compatíveis com módulos fazem o contrário.

Se você usar o webpack, poderá definir destinos diferentes nas configurações para duas versões separadas do aplicativo:

  • Uma versão somente para navegadores compatíveis com módulos.
  • Uma versão que inclui um script compilado que funciona em qualquer navegador legada. O tamanho do arquivo é maior, já que a transpilação precisa oferecer suporte a uma variedade maior de navegadores.

Agradecemos a Connor Clark e Jason Miller pelas avaliações.