Nesse artigo vamos ver em detalhes como os atributos async
e defer
se comportam ao declarar seus arquivos JavaScript no HTML
. Pois, saber onde colocar a tag script
no HTML
tem impacto direto no desempenho da sua página.
Declaração de arquivos JavaScript sem atributos
Basicamente são as duas formas de declarar nossos scripts, dentro da tag head
ou ao final da tag body
. Sabendo disso temos que escolher se queremos que os scripts carreguem antes ou depois do carregamento do HTML. Para carregar os scripts antes do conteúdo HTML precisamos a tag script
dentro da tag head
, pois todo documento é lido pelo navegador de cima para baixo. Logo, se quisermos que os scripts carreguem por último, devemos colocar a tag script
ao final da tag body
. Vamos ver cada uma dessas formas funcionam.
Arquivos JavaScript no head
Vamos testar primeiro a tag script
dentro da tag head
. Em primeiro lugar, antes de iniciar qualquer carregamento da página o navegador fará o download e execução dos scripts. Consequentemente fazendo com que sua página fique mais lenta e com aquela tela em branco enquanto a carrega, dependendo do tamanho dos arquivos, esse processo pode levar algum tempo.
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Arquivo Javascript -->
<script src="script.js"></script>
<title>TreinaWeb</title>
</head>
Veja o tempo que o usuário fica na sua página até começar a analisar o HTML
. Esse tempo para carregar faz com que a experiência do usuário seja prejudicada. Por esse motivo não é recomendado a declaração dos scripts dentro da tag head
.
Curso JavaScript - Fundamentos
Conhecer o cursoArquivos JavaScript no final do body
A forma que todos já ouvimos é a de colocar os arquivos de JavaScript ao final da tag body
. Além de ser o recomendado faz todo sentido, pois se queremos fazer alguma ação em um botão, por exemplo, esse mesmo botão já deverá ter sido lido pelo navegador.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TreinaWeb</title>
</head>
<body>
<!--Inicio do Conteúdo -->
<!--Fim do Conteúdo -->
<!-- Arquivo JavaScript -->
<script src="script.js"></script>
</body>
</html>
Essa declaração de arquivos JavaScript é a mais comum, quando são declarados dessa forma seu carregamento será lido pelos navegadores desse jeito:
A imagem a cima é bem explicativa, quando um navegador envia uma requisição para abrir uma página, ela será lida de cima para baixo e da esquerda para direita. Porém, veja que quando o navegador chega nos seus scripts ele para até finalizar o download e executar, só após isso finaliza 100% do HTML
.
Declaração de arquivos JavaScript com async e defer
Para não ficarmos limitados apenas a essas duas maneiras ditas anteriormente existem dois atributos que podem mudar a forma como os scripts sao carregados. Eles são o async
e o defer
. Vamos ver como esses atributos funcionam em detalhes.
<script defer src="script.js"></script>
<script async src="script.js"></script>
Como async funciona.
Esse atributo, diferente da tag sozinha, irá fazer o download dos scripts junto da página, o que já é uma vantagem, mas ao final do download dos scripts irá parar a análise do HTML
e executar os scripts, mesmo se seu arquivo estiver no head
do documento, dessa forma:
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Arquivo JavaScript *async* -->
<script async src="script.js"></script>
<title>TreinaWeb</title>
</head>
<body>
<!--Inicio do Conteúdo -->
<!--Fim do Conteúdo -->
</body>
</html>
Veja que a análise do HTML e o download dos scprits são feitos simultaneamente, mas independente do momento que estiver a análise do documento, ao finalizar o download dos scripts ele irá parar e executa-los, após isso irá seguir com a análise do HTML
por completo.
Curso Jest - Testes unitários
Conhecer o cursoComo ‘defer’ funciona
Já utilizando o defer
além do download e análise simultânea, o carregamento do seu HTML
não será interrompido em nenhum momento para a execução dos scripts. Eles são executados apenas quando o carregamento de todo o documento estiver concluído. Podendo também ser colocado no head
, vamos ver como esse atributo se comporta no nosso gráfico.
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Arquivo JavaScript *defer* -->
<script defer src="script.js"></script>
<title>TreinaWeb</title>
</head>
Quando utilizar esses atributos?
Para resumir, como havia dito no início, tudo vai depender da sua necessidade, agora que já possui o conhecimento das diferentes maneiras de declarar a importação de scripts em arquivos HTML, você pode utiliza-los da maneira que for mais conveniente para seu projeto, já que esses atributos têm suporte para quase todos os navegadores atuais.
Qual é o melhor?
Isso vai depender muito se você irá ter apenas um arquivo ou vários para mesma página e se um arquivo depende de outro para funcionar perfeitamente. Sabemos que em grandes projetos é bem comum utilizar mais de um arquivo JavaScript na sua página.
Um exemplo é o Bootstrap, na versão 4 ele utilizava até três arquivos JavaScript para funcionar o Popper, o próprio JavaScript do Bootstrap e o jQuery, necessitando de uma sequência específica para funcionar, nesse caso o atributo defer
irá te atender melhor, pois ele obedece à ordem de execução declarada inicialmente no HTML
.
Já se seu script não necessita de nenhum elemento HTML
carregado, nem depende de nenhum outro arquivo para funcionar corretamente o async
será bem útil, pois como o nome já sugere ele trabalha de forma assíncrona, ou seja, irá executar no momento em que for concluído download dos scripts independentemente se a página está carregada ou não.