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 um trabalho extra para garantir que todo o código escrito seja compatível com cada navegador que você planeja segmentar. Se você quiser usar novos recursos da linguagem JavaScript, será necessário transpilar esses recursos para formatos compatíveis com versões anteriores de navegadores que não oferecem suporte a eles.

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

Para usar o Babel e transpilar apenas o que é necessário para seus usuários, faça o seguinte:

  1. Identifique os navegadores que você quer segmentar.
  2. Use @babel/preset-env com os destinos de navegador apropriados.
  3. Use <script type="module"> para parar de enviar códigos transpilados para navegadores que não precisam deles.

Identifique os navegadores que você quer segmentar

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

Usar @babel/preset-env

A transpilação de códigos geralmente resulta em um arquivo maior do que os originais. Ao minimizar a quantidade de compilação, você pode reduzir o tamanho dos pacotes para melhorar a performance 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 oferece vários predefinições que agrupam plug-ins. Use @babel/preset-env para incluir apenas as transformações e os polyfills necessários 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 apropriada ao campo browsers. @babel/preset-env é integrado ao browserslist, uma configuração de código aberto compartilhada entre diferentes ferramentas para segmentar navegadores. Uma lista completa de consultas compatíveis está na documentação do browserslist. Outra opção é usar um arquivo .browserslistrc para listar os ambientes que você quer segmentar.

O valor ">0.25%" informa ao Babel para 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ódigos transpilados desnecessários 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" transpila seu código para as duas versões mais recentes de cada navegador, o que significa que o suporte é oferecido para navegadores descontinuados, como o Internet Explorer. Isso pode aumentar desnecessariamente o tamanho do 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 modernos

@babel/preset-env agrupa vários recursos de sintaxe do JavaScript em coleções, ativando e desativando-os com base nos navegadores de destino especificados. Embora isso funcione bem, uma coleção inteira de recursos de sintaxe é transformada quando um navegador segmentado contém um bug com apenas um recurso. Isso geralmente 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 que está quebrada em alguns navegadores para a sintaxe equivalente mais próxima que não está quebrada 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 esta otimização, verifique se você tem o @babel/preset-env 7.10 ou mais recente instalado e defina a bugfixes propriedade 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. Você pode usar módulos para criar scripts que podem importar e exportar de outros módulos, mas também pode usá-los com @babel/preset-env para segmentar apenas navegadores que oferecem suporte a eles.

Em vez de consultar versões específicas do navegador ou participação de mercado, considere especificar "esmodules" : true no 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 compatíveis com ambientes que oferecem suporte a módulos JavaScript. Ao fazer isso, você simplifica o processo de garantir que apenas códigos transpilados sejam usados para navegadores que realmente precisam deles.

Navegadores que oferecem suporte a módulos ignoram scripts com um atributo nomodule. Por outro lado, 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 scripts de duas versões de um aplicativo sejam incluídos assim:

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

Navegadores que oferecem suporte a módulos buscam e executam main.mjs e ignoram compiled.js. Navegadores sem suporte a módulos fazem o oposto.

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

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

Agradecemos a Connor Clark e Jason Miller pelas análises.