• A posição importa
  • Async e Defer
  • Comparação de desempenho
    • Sem defer ou async, na cabeça
    • Sem deferimento ou assíncrono, no corpo
    • Com assíncrono, na cabeça
    • Com deferimento, na cabeça
  • Blocking parsing
  • Blocking rendering
  • domInteractive
  • Keeping things in order
  • Just me say the best way

Quando carregar um script em uma página HTML, você precisa ter cuidado para não prejudicar a performance de carregamento da página.

Um script é tradicionalmente incluído na página desta forma:

<script src="https://flaviocopes.com/javascript-async-defer/script.js"></script>

Quando o analisador de HTML encontrar esta linha, será feito um pedido para buscar o script, e o script será executado.

Após este processo ser feito, o analisador pode continuar, e o resto do HTML pode ser analisado.

Como você pode imaginar, esta operação pode ter um enorme impacto no tempo de carregamento da página.

Se o script demorar um pouco mais para carregar do que o esperado, por exemplo, se a rede estiver um pouco lenta ou se você estiver em um dispositivo móvel e a conexão estiver um pouco desleixada, o visitante provavelmente verá uma página em branco até que o script seja carregado e executado.

A posição importa

Quando você aprende HTML pela primeira vez, é dito que as tags do script estão ao vivo em <head> tag:

 <html> <head> <title>Title</title> <script src="https://flaviocopes.com/javascript-async-defer/script.js"></script> </head> <body> ... </body></html> 

Como eu disse anteriormente, quando o analisador encontra esta linha, ele vai buscar o script e o executa. Então, depois de terminar esta tarefa, ele passa a analisar o corpo.

Isto é ruim porque há um grande atraso introduzido. Uma solução muito comum para esse problema é colocar a tag script no final da página, pouco antes do fechamento </body> tag.

Ao fazer isso, o script é carregado e executado após toda a página já ter sido analisada e carregada, o que é uma enorme melhoria em relação à tag head alternative.

Esta é a melhor coisa que você pode fazer se precisar suportar navegadores mais antigos que não suportam duas características relativamente recentes do HTML: async e defer.

Async e Defer

Both async e defer são atributos booleanos. O seu uso é similar:

<script async src="https://flaviocopes.com/javascript-async-defer/script.js"></script>
<script defer src="https://flaviocopes.com/javascript-async-defer/script.js"></script>

se especificar ambos, async tem precedência sobre os browsers modernos, enquanto browsers mais antigos que suportam defer mas não async irão cair para defer.

Estes atributos só fazem sentido quando se usa o script na parte head da página, e são inúteis se você colocar o script no rodapé body, como vimos acima.

Comparação de performance

Sem adiamento ou async, na cabeça

Aqui está como uma página carrega um script sem adiamento ou async, coloque na porção head da página:

A análise é pausada até que o script seja buscado, e executado. Uma vez feito isto, o parsing é retomado.

Sem adiamento ou async, no corpo

Aí está como uma página carrega um script sem adiamento ou async, colocado no final da tag body, pouco antes de fechar:

O parsing é feito sem pausas, e quando termina, o script é buscado, e executado. O parsing é feito antes mesmo do download do script, então a página aparece para o usuário muito antes do exemplo anterior.

Com async, na cabeça

Aí está como uma página carrega um script com async, colocado na tag head:

O script é buscado de forma assíncrona, e quando está pronto a análise HTML é pausada para executar o script, então ele é retomado.

Com deferir, na cabeça

Aí está como uma página carrega um script com defer, colocado na tag head:

O script é obtido de forma assíncrona, e é executado somente após a análise do HTML ser feita.

Parsing termina exatamente como quando colocamos o script no final da tag body, mas em geral a execução do script termina bem antes, porque o script foi baixado em paralelo com a análise do HTML.

Então esta é a solução vencedora em termos de velocidade 🏆

Blocking parsing

async bloqueia o parsing da página enquanto defer não.

Blocking rendering

Nem async nem defer garante qualquer coisa no bloqueio da renderização. Isto é com você e seu script (por exemplo, assegurando que seus scripts sejam executados após o evento onLoad).

domInteractive

Scripts marcados com defer são executados logo após o evento domInteractive, que acontece após o HTML ser carregado, analisado e o DOM ser construído.

CSS e as imagens neste ponto ainda devem ser analisadas e carregadas.

Após isto ser feito, o navegador emitirá o evento domComplete, e então onLoad.

domInteractive é importante porque seu tempo é reconhecido como uma medida da velocidade de carregamento percebida. Veja o MDN para mais.

>

Coisas mantidas em ordem

Outro case pro defer: scripts marcados async são executados em ordem casual, quando eles ficam disponíveis. Os scripts marcados com defer são executados (após a conclusão da análise) na ordem em que são definidos na marcação.

Apenas me diga a melhor maneira

O melhor a fazer para acelerar o carregamento da sua página ao usar scripts é colocá-los no head, e adicionar um atributo defer ao seu script tag:

<script defer src="https://flaviocopes.com/javascript-async-defer/script.js"></script>

Este é o cenário que aciona o evento domInteractive mais rápido.

Considerando os prós de defer, parece ser uma escolha melhor do que async numa variedade de cenários.

A menos que você esteja bem em atrasar a primeira renderização da página, certifique-se de que quando a página for parsed o JavaScript que você quer já está executado.

Download meu JavaScript grátis Manual para iniciantes

Outros tutoriais do navegador:

  • Alguns truques úteis disponíveis em HTML5
  • Como eu fiz um CMS-trabalho baseado em website offline
  • O Guia Completo para Aplicações Web Progressivas
  • O Fetch API
  • O Guia Push API
  • O Canal de Mensagens API
  • >

  • Tutorial de Serviços aos Trabalhadores
  • O Guia de Cache API
  • >

  • O Guia de Notificação API
  • >

  • Dividir em IndexedDB
  • O API de Selecionadores: querySelector e querySelectorAll
  • Eficientemente carregar JavaScript com defer e async
  • O Modelo de Objecto de Documento (DOM)
  • A API de Armazenamento Web: armazenamento local e armazenamento de sessão
  • Aprenda como funcionam os Cookies HTTP
  • A API de História
  • O Formato de Imagem WebP
  • XMLHttpRequest (XHR)
  • >

  • Um tutorial SVG detalhado
  • O que são URLs de dados
  • >

  • Roadmap para aprender a Plataforma Web
  • >

  • CORS, Cross-Origin Resource Sharing
  • Trabalhadores Web
  • O guia requestAnimationFrame()
  • Qual é o Doctype
  • Trabalhando com as Ferramentas de Desenvolvimento Consola e a API da Consola
  • A API da Síntese de Fala
  • Como esperar pelo evento DOM pronto em JavaScript simples
  • Como adicionar uma classe a um DOM element
  • Como fazer loop sobre elementos DOM da querySelectorAll
  • Como remover uma classe de um elemento DOM
  • Como verificar se um elemento DOM tem uma classe
  • Como alterar o valor de um nó DOM
  • Como adicionar um evento de clique a uma lista de elementos DOM retornados da querySelectorAll
  • WebRTC, a Real Time Web API
  • Como obter a posição de rolagem de um elemento em JavaScript
  • Como substituir um elemento DOM
  • Como aceitar apenas imagens em um campo de arquivo de entrada
  • Por que usar uma versão de pré-visualização de um navegador?
  • >

  • O objecto Blob
  • O objecto FileReader
  • >

  • O objecto FileList
  • >

  • O objecto FileList
  • >

  • ArrayBuffer
  • >

  • ArrayBufferView
  • >

  • O objecto URL
  • >

  • Tipo Arrays
  • O Objeto DataView
  • O API BroadcastChannel API
  • O API Streams API
  • O Objeto FormData
  • O Objeto Navigator
  • Como usar o API Geolocation
  • Como usar getUserMedia()
  • Como usar o Drag and Drop API
  • Como trabalhar com a rolagem em páginas Web
  • Mandling forms in JavaScript
  • Eventos de teclado
  • Mouse events
  • Touch events
  • Como remover todas as crianças de um elemento DOM
  • Como criar um atributo HTML usando vanilla Javascript
  • Como verificar se uma caixa de seleção está marcada usando JavaScript?
  • Como copiar para a área de transferência usando JavaScript
  • Como desativar um botão usando JavaScript
  • Como tornar uma página editável no navegador
  • Como para obter valores de string de consulta em JavaScript com URLSearchParams
  • Como remover todos os CSS de uma página de uma só vez
  • Como usar insertAdjacentHTML
  • Safari, avisar antes de desistir
  • Como adicionar uma imagem ao DOM usando JavaScript
  • Como reiniciar um formulário
  • Como usar o Google Fonts

Deixe uma resposta

O seu endereço de email não será publicado.