- 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
>
>
>
>
>
>
>
>
>
>
>
>
>