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

Criar sites que funcionam bem em todos os principais navegadores é um princípio fundamental de um ecossistema aberto da Web. No entanto, isso significa um trabalho adicional para garantir que todo o código que você escreve seja compatível com cada navegador que você planeja segmentar. Se você quiser usar novos recursos de linguagem JavaScript, vai precisar transcompilar esses recursos em formatos compatíveis com versões anteriores para navegadores que ainda não têm 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ê esteja usando o Babel e, portanto, siga as instruções de configuração para incluí-lo no seu 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 e transcompilar apenas o que é necessário para os usuários, você precisa:

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

Identificar quais navegadores você quer segmentar

Antes de começar a modificar a forma como o código é transcompilado no aplicativo, você precisa identificar quais navegadores acessam seu aplicativo. Analise quais navegadores seus usuários estão usando atualmente, bem como aqueles que você planeja segmentar para tomar uma decisão informada.

Usar @babel/preset-env

A transcompilação de código geralmente resulta em um arquivo com um tamanho maior do que as formas originais. Ao minimizar a quantidade de compilação, você pode 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 uma série de predefinições que agrupam os plug-ins. Use @babel/preset-env para incluir apenas as transformações e polyfills necessários para os navegadores que serão segmentados.

Inclua @babel/preset-env na matriz presets do 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 apropriada ao campo browsers. O @babel/preset-env se integra à lista de navegadores, uma configuração de código aberto compartilhada entre diferentes ferramentas para segmentar navegadores. Há uma lista completa de consultas compatíveis na documentação da 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 representam mais de 0,25% do uso global. Isso garante que o pacote não contenha código transcompilado 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 todos os navegadores, o que significa que há suporte para navegadores descontinuados, como o Internet Explorer. Isso pode aumentar desnecessariamente o tamanho do pacote se você não quiser que esses navegadores sejam usados para acessar o aplicativo.

Por fim, você deve selecionar a combinação apropriada de consultas para segmentar apenas os navegadores que atendam às suas necessidades.

Ativar correções de bugs modernas

O @babel/preset-env agrupa vários recursos de sintaxe 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ódigos transformados do que o necessário.

Originalmente desenvolvida como uma predefinição separada, a opção de correções de bugs em @babel/preset-env resolve esse problema convertendo a sintaxe moderna 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 compatibilidade em todos os navegadores de destino. Para usar essa otimização, verifique se você tem o @babel/preset-env 7.10 ou mais recente instalado e defina a propriedade bugfixes como true:

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

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

Usar <script type="module">

Módulos JavaScript, ou módulos ES, são um recurso relativamente novo com suporte em todos os principais navegadores. Você pode usar módulos para criar scripts que possam importar e exportar de outros módulos, mas também pode usá-los com @babel/preset-env para segmentar apenas navegadores com suporte a 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 mais recentes do ECMAScript compilados com o Babel já são aceitos em ambientes com suporte a módulos JavaScript. Ao fazer isso, você simplifica o processo de garantir que apenas o código transcompilado seja usado para navegadores que realmente precisam dele.

Os navegadores compatíveis com 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>

Navegadores compatíveis com 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 oposto.

Se você usar o webpack, será possível definir destinos diferentes nas configurações para duas versões separadas do seu aplicativo:

  • Uma versão apenas para navegadores que suportam módulos.
  • Uma versão que inclui um script compilado que funciona em qualquer navegador legado. Esse arquivo tem um tamanho maior, já que a transcompilação precisa oferecer suporte a uma maior variedade de navegadores.

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