Onde devo colocar as tags <script> na marcação HTML?


1488

Ao incorporar JavaScript em um documento HTML, onde é o local apropriado para colocar as <script>tags e incluir o JavaScript? Eu me lembro que você não deveria colocá-las na <head>seção, mas a colocação no início da <body>seção também é ruim, pois o JavaScript terá que ser analisado antes que a página seja renderizada completamente (ou algo assim). Isso parece deixar o final da <body>seção como um local lógico para as <script>tags.

Então, onde é o lugar certo para colocar as <script>tags?

(Esta pergunta faz referência a essa pergunta , na qual foi sugerido que as chamadas de função JavaScript devam ser movidas de <a>tags para <script>tags. Estou usando especificamente o jQuery, mas respostas mais gerais também são adequadas.)


caso você também esteja apenas procurando uma solução simples e esteja usando algum gerador do lado do servidor como Jekyll, recomendo incluir o script com ele. muito mais simples!
Cregox 20/09/19

Respostas:


1864

Aqui está o que acontece quando um navegador carrega um site com uma <script>tag:

  1. Busque a página HTML (por exemplo, index.html)
  2. Comece a analisar o HTML
  3. O analisador encontra uma <script>marca referenciando um arquivo de script externo.
  4. O navegador solicita o arquivo de script. Enquanto isso, o analisador bloqueia e para de analisar o outro HTML em sua página.
  5. Depois de algum tempo, o script é baixado e executado posteriormente.
  6. O analisador continua analisando o restante do documento HTML.

O passo 4 causa uma má experiência do usuário. Seu site basicamente pára de carregar até que você baixe todos os scripts. Se há algo que os usuários odeiam, está esperando o carregamento de um site.

Por que isso acontece?

Qualquer script pode inserir seu próprio HTML via document.write()ou outras manipulações DOM. Isso implica que o analisador precisa esperar até que o script seja baixado e executado antes de poder analisar com segurança o restante do documento. Afinal, o script poderia ter inserido seu próprio HTML no documento.

No entanto, a maioria dos desenvolvedores de JavaScript não manipula mais o DOM enquanto o documento está sendo carregado. Em vez disso, eles esperam até o documento ser carregado antes de modificá-lo. Por exemplo:

<!-- index.html -->
<html>
    <head>
        <title>My Page</title>
        <script src="my-script.js"></script>
    </head>
    <body>
        <div id="user-greeting">Welcome back, user</div>
    </body>
</html>

Javascript:

// my-script.js
document.addEventListener("DOMContentLoaded", function() { 
    // this function runs when the DOM is ready, i.e. when the document has been parsed
    document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});

Como o seu navegador não sabe que o my-script.js não modifica o documento até que ele seja baixado e executado, o analisador para de analisar.

Recomendação antiquada

A abordagem antiga para resolver esse problema era colocar <script>tags na parte inferior do seu <body>, porque isso garante que o analisador não seja bloqueado até o final.

Essa abordagem tem seu próprio problema: o navegador não pode iniciar o download dos scripts até que todo o documento seja analisado. Para sites maiores com scripts e folhas de estilo grandes, a capacidade de fazer o download do script o mais rápido possível é muito importante para o desempenho. Se o seu site não carregar dentro de 2 segundos, as pessoas irão para outro site.

Em uma solução ideal, o navegador começaria a baixar seus scripts o mais rápido possível, enquanto analisava o restante do documento.

A abordagem moderna

Hoje, os navegadores suportam os atributos asynce defernos scripts. Esses atributos informam ao navegador que é seguro continuar analisando enquanto os scripts estão sendo baixados.

assíncrono

<script src="path/to/script1.js" async></script>
<script src="path/to/script2.js" async></script>

Os scripts com o atributo assíncrono são executados de forma assíncrona. Isso significa que o script é executado assim que é baixado, sem bloquear o navegador enquanto isso.
Isso implica que é possível fazer o download e executar o script 2 antes do script 1.

De acordo com http://caniuse.com/#feat=script-async , 97,78% de todos os navegadores suportam isso.

adiar

<script src="path/to/script1.js" defer></script>
<script src="path/to/script2.js" defer></script>

Os scripts com o atributo defer são executados em ordem (ou seja, primeiro script 1, depois script 2). Isso também não bloqueia o navegador.

Diferentemente dos scripts assíncronos, os scripts de adiamento são executados somente após o carregamento do documento inteiro.

De acordo com http://caniuse.com/#feat=script-defer , 97,79% de todos os navegadores suportam isso. 98,06% o apóiam pelo menos parcialmente.

Uma observação importante sobre a compatibilidade do navegador: em algumas circunstâncias, o IE <= 9 pode executar scripts adiados fora de ordem. Se você precisar oferecer suporte a esses navegadores, leia isso primeiro!

Conclusão

O estado da arte atual é colocar scripts na <head>tag e usar os atributos asyncou defer. Isso permite que seus scripts sejam baixados o mais rápido possível, sem bloquear o navegador.

O bom é que seu site ainda deve carregar corretamente nos 2% dos navegadores que não suportam esses atributos enquanto acelera os outros 98%.


63
Estou surpreso ninguém citou explicação ... do Google developers.google.com/speed/docs/insights/BlockingJS
Casey Falk

6
Não sei ao certo o que toca o DOM e o que não toca. Você pode esclarecer? É seguro fazer uma carga assíncrona em algo como jquery.js?
Doug

7
@ Doug Por exemplo, document.writeopera no dom. A questão não é se um script manipula o dom, mas quando o faz. Desde que toda a manipulação do Dom aconteça após o domreadyevento ter sido acionado, você estará bem. O jQuery é uma biblioteca e, como tal, não manipula o dom por si só.
Bart Bart

24
Esta resposta é enganosa. Os navegadores modernos não param de analisar quando atingem uma tag de script síncrona que pode afetar o HTML, eles apenas param de renderizar / executar e continuam analisando de maneira otimista para começar a baixar outros recursos que provavelmente serão solicitados posteriormente se nenhum HTML for afetado.
Fabio Beltramini

40
Por que os atributos asynce defernão são usados ​​em lugar algum? Quero dizer, eu vi muitas fontes HTML da Internet e não vejo os atributos asynce em deferlugar algum. ...?
101316 John

239

Pouco antes da etiqueta do corpo de fechamento, conforme indicado em

http://developer.yahoo.com/performance/rules.html#js_bottom

Coloque os scripts na parte inferior

O problema causado pelos scripts é que eles bloqueiam downloads paralelos. A especificação HTTP / 1.1 sugere que os navegadores baixem não mais que dois componentes em paralelo por nome de host. Se você exibir suas imagens a partir de vários nomes de host, poderá obter mais de dois downloads em paralelo. Enquanto um script está sendo baixado, no entanto, o navegador não inicia outros downloads, mesmo em nomes de host diferentes.


7
Concordo com o conceito e sua explicação. Mas o que acontece se o usuário começar a brincar com a página. Suponha que eu tenha um menu suspenso AJAX que começará a carregar depois que a página aparecer para o usuário, mas enquanto estiver carregando, o usuário clica nela! E se um usuário 'realmente impaciente' enviar o formulário?
precisa

9
@Hermant Comentário antigo, mas você pode fazer o truque desabilitando os campos por padrão e habilitando-os usando JS quando o DOM estiver totalmente carregado. É o que o Facebook parece estar fazendo hoje em dia.
Novato

2
Apenas testei isso com o chrome, para verificar se ainda é o mesmo. Isto é. Você pode verificar as diferenças no tempo de carregamento da página dos seus navegadores aqui. stevesouders.com/cuzillion
cypher

46
Se essa é uma prática recomendada, por que o estouro de pilha inclui todas as suas tags de script em <head>? :-P
Felipe

10
Em alguns casos, especialmente em sites pesados ​​ajax, o carregamento na cabeça pode resultar em tempos de carregamento mais rápidos. Consulte: encosia.com/dont-let-jquerys-document-ready-slow-you-down (observe que a função "live ()" está obsoleta no jquery, mas o artigo ainda se aplica aos "on ()" ou " delegar "função). O carregamento em <head> também pode ser necessário para garantir o comportamento correto, conforme apontado por @Hermant. Finalmente, modernizr.com/docs recomenda colocar seus scripts no <head> pelos motivos explicados em seu site.
Nathan

77

Tags de script sem bloqueio podem ser colocadas em qualquer lugar:

<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
  • async O script será executado de forma assíncrona assim que estiver disponível
  • defer script é executado quando o documento termina de analisar
  • async defer script volta ao comportamento de adiamento se o assíncrono não for suportado

Esses scripts serão executados de forma assíncrona / após o documento estar pronto, o que significa que você não pode fazer isso:

<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
  * might throw "jQuery is not defined" error
  * defer will not work either
-->

Ou isto:

<script src="document.write(something).js" async></script>
<!--
  * might issue "cannot write into document from an asynchronous script" warning
  * defer will not work either
-->

Ou isto:

<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
  * might throw "jQuery is not defined" error (no guarantee which script runs first)
  * defer will work in sane browsers
-->

Ou isto:

<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
  * might not locate #header (script could fire before parser looks at the next line)
  * defer will work in sane browsers
-->

Dito isto, os scripts assíncronos oferecem estas vantagens:

  • Download paralelo de recursos : o
    navegador pode baixar folhas de estilo, imagens e outros scripts em paralelo, sem aguardar o download e a execução de um script.
  • Independência da ordem de origem :
    você pode colocar os scripts dentro da cabeça ou do corpo sem se preocupar com o bloqueio (útil se você estiver usando um CMS). A ordem de execução ainda é importante.

É possível contornar os problemas da ordem de execução usando scripts externos que suportam retornos de chamada. Muitas APIs JavaScript de terceiros agora oferecem suporte à execução sem bloqueio. Aqui está um exemplo de carregamento da API do Google Maps de forma assíncrona .


2
Essa é a resposta correta para hoje - usar essa abordagem significa que é mais fácil manter seus widgets independentes, sem necessidade de <head>lógica lógica sofisticada .
Daniel Sokolowski

1
Estou confuso porque você não pode usar asyncou deferquando incluindo jQuery como especificado no segundo bloco: <script src="jquery.js" async></script>. Você é capaz de explicar o porquê? Eu pensei que precisava ter a tag assíncrona para desempenho - de acordo com a resposta aceita - para que minha página seja carregada mesmo enquanto o jQuery ainda estiver carregando]. Obrigado!
Elbowlobstercowstand 6/08/2015

3
@elbow 99% das vezes <script src=jquery.js>é seguido por $(function(){ ... })blocos em algum lugar da página. O carregamento assíncrono não garante que o jQuery será carregado no momento em que o navegador tentar analisar esses blocos, portanto, ele aumentará o erro $ não está definido (você pode não receber o erro se o jQuery tiver sido carregado do cache). Respondi a uma pergunta sobre o carregamento do jQuery de forma assíncrona e preserve $(function(){ ... }). Vou ver se eu poderia encontrá-lo, ou você pode olhar para esta questão: stackoverflow.com/q/14811471/87015
Salman A

1
@SalmanA Thank you! Sim, eu caio nesses 99%. Primeiro eu preciso da jquerylib para carregar, depois meus .jsscripts restantes . Quando declaro asyncou deferna jquerytag lib script, meus .jsscripts não funcionam. Eu pensei $(function(){ ... })que protegia isso - acho que não. Solução atual: Eu não adiciono deferou asyncno jqueryscript lib, mas adiciono asyncnos meus .jsscripts de acompanhamento . Nota: a razão que eu estou fazendo qualquer disto é para tornar o Google Page Speed feliz. Obrigado novamente pela ajuda! Qualquer outro conselho é bem-vindo. (Ou um link para sua resposta anterior). :)
elbowlobstercowstand

@elbow Consulte stackoverflow.com/a/21013975/87015 , ele fornecerá apenas uma idéia, mas não a solução completa. Você poderia procurar por "bibliotecas jquery async loader".
Salman A

38

O conselho padrão, promovido pelo Yahoo! Equipe de desempenho excepcional, é colocar as <script>tags no final do corpo do documento para que elas não bloqueiem a renderização da página.

Mas existem algumas abordagens mais recentes que oferecem melhor desempenho, conforme descrito nesta resposta sobre o tempo de carregamento do arquivo JavaScript do Google Analytics:

Existem alguns ótimos slides de Steve Souders (especialista em desempenho do lado do cliente) sobre:

  • Técnicas diferentes para carregar arquivos JavaScript externos em paralelo
  • seu efeito no tempo de carregamento e na renderização da página
  • que tipo de indicadores "em andamento" o navegador exibe (por exemplo, 'carregando' na barra de status, cursor do mouse em ampulheta).

25

Se você estiver usando o JQuery, coloque o javascript onde achar melhor e use $(document).ready()para garantir que as coisas sejam carregadas corretamente antes de executar qualquer função.

Em uma nota lateral: eu gosto de todas as minhas tags de script na <head>seção, pois esse parece ser o lugar mais limpo.


14
na cabeça ... er? <header>?
precisa saber é o seguinte

7
Observe que o uso $(document).ready()não significa que você pode colocar seu JavaScript em qualquer lugar que desejar - você ainda precisará colocá-lo após o local <script src=".../jquery.min.js">onde você incluir o jQuery, para que ele $exista.
Rory O'Kane

2
Não é ideal colocar tags de script na seção <head> - isso atrasará a exibição da parte visível da página até que os scripts sejam carregados.
CyberMonk

Não, @Dan, um headerelemento faz parte do conteúdo do documento HTML e deve ocorrer uma ou mais vezes na tag head do bodyelemento, . The para metadados e dados sem conteúdo do documento. Trata-se, nos dias de hoje, com defere asyncum lugar ideal para tags de script. headerOs elementos devem conter apenas informações que descrevam a seção do documento a seguir.
ProfK 29/03

1
@ProfK, Dan estava se referindo à pergunta original não editada quando postou isso há mais de 4 anos. Como você pode ver, a pergunta foi editada um ano depois.
kojow7

18

A abordagem moderna em 2019 está usando scripts do tipo de módulo ES6 .

<script type="module" src="..."></script>

Por padrão, os módulos são carregados de forma assíncrona e adiada. ou seja, você pode colocá-los em qualquer lugar e eles serão carregados em paralelo e executados quando a página terminar de carregar.

As diferenças entre um script e um módulo são descritas aqui:

https://stackoverflow.com/a/53821485/731548

A execução de um módulo comparado a um script é descrita aqui:

https://developers.google.com/web/fundamentals/primers/modules#defer

O suporte é mostrado aqui:

https://caniuse.com/#feat=es6-module


bom informações para adicionar à base de conhecimento
Sagar

1
Apenas observe que isso não funcionará se você estiver apenas experimentando coisas no seu sistema de arquivos local sem servidor. Pelo menos no Chrome, você recebe um erro de origem cruzada tentando carregar os js do HTML, mesmo que ambos tenham a mesma origem, seu sistema de arquivos.
Hippietrail 10/09/19

11

XHTML não validará se o script estiver em outro lugar que não esteja dentro do elemento head. Acontece que pode estar em toda parte.

Você pode adiar a execução com algo como jQuery, para que não importe onde foi colocada (exceto por um pequeno desempenho atingido durante a análise).


1
O XHTML será validado com tags de script no corpo, estritas e transitórias. No entanto, as tags de estilo podem estar apenas na cabeça.
I.devries 12/01/09

11
<script src="myjs.js"></script>
</body>

A tag de script deve ser usada sempre antes do fechamento do corpo ou na parte inferior do arquivo HTML .

então você pode ver o conteúdo da página primeiro antes de carregar o arquivo js .

verifique isso se necessário: http://stevesouders.com/hpws/rule-js-bottom.php


2
Isso realmente respondeu à pergunta. Eu queria saber quase todos os exemplos nunca publicado deu o contexto visual adequada de "fim da página"
Ken Ingram

1
Esta resposta é muito enganosa e provavelmente errada. Os artigos no Google e no MDN sugerem que o JS síncrono (que é o caso aqui) sempre bloqueia a construção e a análise do DOM, o que resultará na primeira renderização atrasada. Portanto, você não pode ver o conteúdo da página até que o arquivo JS é buscado e termina a execução, independentemente de onde você colocar seu arquivo JS no documento HTML, desde que ele é síncrono
Lingaraju EV

Também faz referência a pontos feitos em 2009 e não são mais relevantes.
toxaq

7

A resposta convencional (e amplamente aceita) é "na parte inferior", porque todo o DOM será carregado antes que qualquer coisa possa começar a ser executada.

Existem dissidentes, por vários motivos, começando com a prática disponível para iniciar intencionalmente a execução com um evento onload de página.


6

O melhor local para colocar uma <script>tag é antes de fechar a </body>tag , para que o download e a execução não bloqueiem o navegador para analisar o html no documento,

Também o carregamento externo dos arquivos js tem suas próprias vantagens, pois será armazenado em cache pelos navegadores e pode acelerar o tempo de carregamento da página , separa o código HTML e JavaScript e ajuda a gerenciar melhor a base de códigos .

mas os navegadores modernos também suportam algumas outras maneiras ideais como asynce deferpara carregar externos javascriptarquivos.

Assíncrono e adiado

Normalmente, a execução da página HTML começa linha por linha. Quando um elemento JavaScript externo é encontrado, a análise de HTML é interrompida até que um JavaScript seja baixado e esteja pronto para execução. Esta execução da página normal pode ser alterado usando defere asyncatributo.

Defer

Quando um atributo adiado é usado, o JavaScript é baixado paralelamente à análise de HTML, mas será executado somente após a análise completa de HTML.

<script src="/local-js-path/myScript.js" defer></script>

Async

Quando o atributo assíncrono é usado, o JavaScript é baixado assim que o script é encontrado e, após o download, ele é executado de forma assíncrona (paralelamente), juntamente com a análise de HTML.

<script src="/local-js-path/myScript.js" async></script>

Quando usar quais atributos

  • Se o seu script for independente de outros scripts e for modular, use async.
  • Se você estiver carregando script1 e script2 async, ambos serão executados
    paralelamente, juntamente com a análise de HTML, assim que forem baixados
    e disponíveis.
  • Se o seu script depende de outro script, use deferpara ambos:
  • Quando script1 e script2 são carregados nessa ordem defer, o script1 é garantido para executar primeiro,
  • Em seguida, o script2 será executado após o script1 ser totalmente executado.
  • Isso deve ser feito se o script2 depender do script1.
  • Se o seu script for pequeno o suficiente e depender de outro script do tipo async, use-o sem atributos e coloque-o acima de todos os asyncscripts.

referência: knowledgehills.com


3

Depende, se você estiver carregando um script necessário para estilizar sua página / usando ações em sua página (como o clique de um botão), é melhor colocá-lo no topo. Se o seu estilo for 100% CSS e você tiver todas as opções de fallback para as ações dos botões, poderá colocá-lo na parte inferior.

Ou o melhor (se isso não for um problema) é que você pode criar uma caixa de carregamento modal, colocar seu javascript na parte inferior da página e desaparecer quando a última linha do seu script for carregada. Dessa forma, você pode evitar que os usuários usem ações em sua página antes do carregamento dos scripts. E também evite o estilo inadequado.


3

A inclusão de scripts no final é usada principalmente onde o conteúdo / estilos do site deve ser mostrado primeiro.

incluir os scripts na cabeça carrega os scripts mais cedo e pode ser usado antes do carregamento de todo o site.

se os scripts forem inseridos finalmente, a validação ocorrerá somente após o carregamento de todos os estilos e designs, o que não é apreciado por sites com rápida resposta.


2

Dependendo do script e seu uso, o melhor possível (em termos de carregamento da página e tempo de renderização) pode ser não usar uma tag <script> convencional por si só, mas disparar dinamicamente o carregamento do script de forma assíncrona.

Existem algumas técnicas diferentes, mas a mais direta é usar document.createElement ("script") quando o evento window.onload é acionado. Em seguida, o script é carregado primeiro quando a página é renderizada, não afetando o tempo que o usuário precisa esperar para que a página apareça.

Naturalmente, isso requer que o próprio script não seja necessário para a renderização da página.

Para obter mais informações, consulte a publicação dos scripts de acoplamento assíncrono de Steve Souders (criador do YSlow, mas agora no Google).


2
  • Se você ainda se preocupa muito com suporte e desempenho no IE <10, é melhor SEMPRE transformar suas tags de script nas últimas tags do seu corpo HTML. Dessa forma, você tem certeza de que o restante do DOM foi carregado e não bloqueará e renderizará.

  • Se você não se importa muito com o IE <10, convém colocar seus scripts no cabeçalho do documento e usá-lo deferpara garantir que eles sejam executados somente após o carregamento do seu DOM ( <script type="text/javascript" src="path/to/script1.js" defer></script>). Se você ainda deseja que seu código funcione no IE <10, não se esqueça de agrupar seu código de maneira window.onloaduniforme!


Na resposta aceita, isso é chamado de "recomendação antiquada". Se você ainda está falando sério, provavelmente deve produzir alguma referência para apoiá-lo.
Dakab

1

Blocos de script que o DOM carrega até que seja carregado e executado.

Se você colocar scripts no final de <body>todo o DOM, poderá carregar e renderizar (a página será "exibida" mais rapidamente). <script>terá acesso a todos esses elementos DOM.

Por outro lado, colocá-lo após o <body>início ou acima irá executar o script (onde ainda não há elementos DOM).

Você está incluindo o jQuery, o que significa que você pode colocá-lo onde quiser e usar .ready ()


1

Eu acho que depende da execução da página da web. Se a página que você deseja exibir não puder ser exibida corretamente sem antes carregar o JavaScript, inclua o arquivo JavaScript primeiro. Mas se você pode exibir / renderizar uma página da Web sem fazer o download inicial do arquivo JavaScript, coloque o código JavaScript na parte inferior da página. Como emulará um carregamento rápido da página e, do ponto de vista do usuário, parece que a página está carregando mais rapidamente.


1

Você pode colocar a maioria das <script>referências no final de <body>,
mas se houver componentes ativos em sua página que estejam usando scripts externos,
sua dependência (arquivos js) deverá vir antes disso (idealmente no cabeçalho).


1

Antes do final da etiqueta do corpo, a fim de impedir e bloquear a interface do usuário.


-1

No final do documento HTML

Para que isso não afete o carregamento do documento HTML no navegador no momento da execução.


-1

O melhor local para escrever seu JavaScriptcódigo é no final do documento, antes ou logo antes da </body>tag, para carregar o documento primeiro e depois executar o código js.

<script> ... your code here ... </script>
</body>

E se você escrever JQueryo seguinte, pode estar no documento principal e ele será executado após o carregamento do documento:

<script>
$(document).ready(function(){
   //your code here...
});
</script>

ele lançaSyntaxError
Raz

Sua resposta não estava errada, mas precisava urgentemente de ser atualizada.
Paul Carlton

-2

Faz mais sentido para mim incluir o script após o HTML. Porque na maioria das vezes eu preciso que o Dom seja carregado antes de executar meu script. Eu poderia colocá-lo na tag head, mas não gosto de toda a sobrecarga do ouvinte de carregamento de documentos. Quero que meu código seja curto, doce e fácil de ler.

Ouvi dizer que versões antigas do safari eram quarky ao adicionar seu script fora do cabeçalho, mas digo quem se importa. Não conheço ninguém que use essa porcaria velha.

Boa pergunta, a propósito.


-6

Você pode colocar onde deseja os scripts e um não é melhor que outra prática.

a situação é a seguinte:

A página carrega linearmente, "de cima para baixo", portanto, se você colocar o script na cabeça, garante que ele comece a carregar antes de tudo, agora, se você o colocar dentro do corpo misturado ao código, poderá causar um carregamento desagradável da página.

identificar boas práticas não depende de onde.

para apoiá-lo, mencionarei o seguinte:

você pode colocar:

e a página carregará linearmente

página é carregada de forma assíncrona com outro conteúdo

o conteúdo da página será carregado antes e após a conclusão do carregamento, os scripts serão carregados

boa prática aqui seria, quando implementará cada?

Espero ter sido útil, qualquer coisa me responda a esse problema.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.