Quando devo usar Javascript Inline x Externo?

129

Gostaria de saber quando devo incluir scripts externos ou escrevê-los em linha com o código html, em termos de desempenho e facilidade de manutenção.

Qual é a prática geral para isso?

Cenário do mundo real - tenho várias páginas html que precisam de validação de formulário do lado do cliente. Para isso, uso um plugin jQuery que incluo em todas essas páginas. Mas a questão é: devo:

  • escrever os bits de código que configuram esse script embutido?
  • incluir todos os bits em um arquivo que é compartilhado entre todas essas páginas html?
  • incluir cada bit em um arquivo externo separado, um para cada página html?

Obrigado.

Dan Burzo
fonte

Respostas:

114

No momento em que essa resposta foi postada originalmente (2008), a regra era simples: todos os scripts deveriam ser externos. Tanto para manutenção quanto para desempenho.

(Por que desempenho? Porque, se o código for separado, pode ser mais facilmente armazenado em cache pelos navegadores.)

O JavaScript não pertence ao código HTML e, se contém caracteres especiais (como <, >) , ele cria problemas.

Atualmente, a escalabilidade da web mudou. Reduzir o número de solicitações se tornou uma consideração válida devido à latência de fazer várias solicitações HTTP. Isso torna a resposta mais complexa: na maioria dos casos, ainda é recomendável ter JavaScript externo . Mas, em certos casos, especialmente pedaços muito pequenos de código, incorporá-los no HTML do site faz sentido.

Konrad Rudolph
fonte
6
@ Nick: a maioria dos problemas pode ser superada. Melhor não gerá-los, em primeiro lugar.
Konrad Rudolph
17
Às vezes, você obtém melhor desempenho ao inserir. Veja a fonte do google.com . Eles sabem o que estão fazendo.
Callum #
13
@callum O Google tem um caso de uso diferente de 99.999999% dos sites. É claro que eles medem com muito cuidado e até a menor diferença importa. Mas apenas porque descobriram que, em seu caso de uso específico, inlining funciona melhor (provavelmente porque o script muda com muita frequência?) Não significa que podemos derivar uma regra geral disso, ou mesmo que devemos desconsiderar o "convencional" regra (para externalizar scripts).
Konrad Rudolph
8
@KonradRudolph - Concordado, nenhuma regra geral deve ser derivada da abordagem do Google. Só estou dizendo que é uma dica de que pode valer a pena questionar a regra em sua resposta. Enfim, acho que o motivo pelo qual o Google faz isso é reduzir as solicitações de HTTP, e isso pode beneficiar mais de 0,000001% dos sites. A largura de banda está aumentando, mas os tempos de ida e volta permanecem os mesmos. A remoção de uma solicitação HTTP serial inteira às vezes é melhor do que o benefício de cache de JS externo. Depende do tamanho do seu JS, é claro.
Callum
5
@ callum Embora isso seja verdade, o argumento sobre o cache ainda permanece e permanece importante. Reduzir as viagens de ida e volta é importante apenas se seus visitantes não retornarem (e você não obterá hits suficientes da página para torná-lo importante) ou se o seu conteúdo for alterado com tanta frequência que o armazenamento em cache dos arquivos de script não beneficia.
21430 Konrad Rudolph
31

A manutenção é definitivamente um motivo para mantê-los externos, mas se a configuração for de uma linha (ou em geral menor que a sobrecarga HTTP que você obteria para tornar esses arquivos externos), é melhor em termos de desempenho mantê-los alinhados. Lembre-se sempre de que cada solicitação HTTP gera alguma sobrecarga em termos de tempo de execução e tráfego.

Naturalmente, tudo isso se torna irrelevante no momento em que seu código ultrapassa algumas linhas e não é realmente específico para uma única página. No momento em que você desejar reutilizar esse código, torne-o externo. Caso contrário, observe o tamanho e decida.

Horst Gutmann
fonte
5
Essa é uma das minhas preocupações. Ter uma solicitação HTTP separada para algumas linhas de códigos parece um desperdício.
Dan Burzo 26/09/08
Você poderia postar uma configuração de exemplo para o seu código? OMI, se tiver menos de 300 caracteres e for absolutamente específico da página, incline-o.
Horst Gutmann
Esta deve ser a resposta principal imo
sgarcia.dev 8/08/16
@Dan lembre-se de que a solicitação separada acontece apenas na primeira vez. Se você espera que seus usuários carreguem a página mais de uma vez, o cache externo (mesmo que por algumas linhas) é claramente mais rápido do que aguardar os bytes dessas poucas linhas por fio nos n = 2 + carregamentos de página.
Jinglesthula #
@HorstGutmann como o fato de o arquivo ter ajuda externa com capacidade de manutenção? Pessoalmente, prefiro js externos sempre que possível, mas há algo objetivo que facilita a manutenção?
Jinglesthula
21

Externalizar javascript é uma das regras de desempenho do yahoo: http://developer.yahoo.com/performance/rules.html#external

Embora a regra rígida de que você sempre deva externalizar scripts geralmente seja uma boa aposta, em alguns casos, você pode incorporar alguns dos scripts e estilos. No entanto, você deve apenas alinhar as coisas que sabe que melhorarão o desempenho (porque você mediu isso).

Joeri Sebrechts
fonte
1
Eu acho que o Yahoo também recomendam a adição de todo o Javascript em um HTTP chamar também - isso não significa que os scripts devem estar todos no mesmo arquivo durante o desenvolvimento embora
Paul Shannon
Além disso, como observado acima, o HTTP / 2 também altera a prática "1 chamada".
Jinglesthula
19

Se você se preocupa apenas com desempenho, a maioria dos conselhos deste segmento é totalmente errada e está se tornando cada vez mais errada na era do SPA, onde podemos assumir que a página é inútil sem o código JS. Passei inúmeras horas otimizando o tempo de carregamento da página do SPA e verificando esses resultados com diferentes navegadores. Em geral, o aumento de desempenho re-orquestrando seu html pode ser bastante dramático.

Para obter o melhor desempenho, você deve pensar nas páginas como foguetes de dois estágios. Estas duas etapas correspondem aproximadamente a <head>e <body>fases, mas acho que eles em vez como <static>e <dynamic>. A porção estática é basicamente uma constante de seqüência de caracteres que você desliza no tubo de resposta o mais rápido possível. Isso pode ser um pouco complicado se você usar muito middleware que define cookies (eles precisam ser configurados antes de enviar conteúdo http), mas, em princípio, está apenas liberando o buffer de resposta, antes de saltar para algum código de modelo (razor, php, etc) no servidor Pode parecer difícil, mas só estou explicando errado, porque é quase trivial. Como você deve ter adivinhado, essa parte estática deve conter todo o javascript embutido e minificado. Seria algo como

<!DOCTYPE html>
     <html>
         <head>
             <script>/*...inlined jquery, angular, your code*/</script>
             <style>/* ditto css */</style>
         </head>
         <body>
             <!-- inline all your templates, if applicable -->
             <script type='template-mime' id='1'></script>
             <script type='template-mime' id='2'></script>
             <script type='template-mime' id='3'></script>

Como não custa quase nada enviar essa parte pelo fio, você pode esperar que o cliente comece a receber algo em torno de 5ms + latência após conectar-se ao seu servidor. Supondo que o servidor esteja razoavelmente próximo, essa latência pode estar entre 20ms e 60ms. Os navegadores começarão a processar esta seção assim que a receberem, e o tempo de processamento normalmente dominará o tempo de transferência pelo fator 20 ou mais, que agora é sua janela amortizada para o processamento da <dynamic>parte do servidor .

Demora cerca de 50ms para o navegador (chrome, descanse talvez 20% mais lento) para processar jquery + sinalr + angular + animação + toque + rotas + lodash. Isso é incrível por si só. A maioria dos aplicativos da Web possui menos código do que todas as bibliotecas populares reunidas, mas digamos que você tenha o mesmo, por isso ganharíamos latência + 100ms de processamento no cliente (essa conquista de latência vem do segundo bloco de transferência). Quando o segundo pedaço chega, processamos todo o código js e modelos e podemos começar a executar transformações dom.

Você pode objetar que esse método é ortogonal ao conceito embutido, mas não é. Se você, em vez de inlining, vincular a cdns ou seus próprios servidores, o navegador precisará abrir outra conexão (s) e atrasar a execução. Como essa execução é basicamente gratuita (como o servidor está conversando com o banco de dados), deve ficar claro que todos esses saltos custariam mais do que não fazer nenhum salto. Se houvesse uma peculiaridade de navegador que dissesse js externos executados mais rapidamente, poderíamos medir qual fator domina. Minhas medidas indicam que solicitações extras reduzem o desempenho nesse estágio.

Eu trabalho muito com a otimização de aplicativos SPA. É comum as pessoas pensarem que o volume de dados é muito importante, enquanto na verdade a latência e a execução geralmente dominam. As bibliotecas minificadas listadas adicionam até 300kb de dados, e são apenas 68 kb gzipados, ou 200ms de download em um telefone de 2mbit 3g / 4g, que é exatamente a latência que seria necessária no mesmo telefone para verificar se ele possuía os mesmos dados já em seu cache, mesmo que fosse proxy em cache, porque o imposto de latência móvel (latência do telefone à torre) ainda se aplica. Enquanto isso, as conexões de área de trabalho com menor latência de primeiro salto geralmente têm maior largura de banda.

Em resumo, agora (2014), é melhor incorporar todos os scripts, estilos e modelos.

EDITAR (MAIO DE 2016)

À medida que os aplicativos JS continuam a crescer, e algumas das minhas cargas agora empilham mais de 3 megabytes de código minificado, torna-se óbvio que pelo menos as bibliotecas comuns não devem mais ser incorporadas.

Gleno
fonte
Agora não recebi a janela que agora é sua janela amortizada para o processamento da parte da parte <dinâmica> no servidor - O servidor processa o que for necessário e só depois atende todo o html renderizado (cabeça + corpo), que outro processamento do servidor é necessário depois disso?
BornToCode
@BornToCode A idéia é dar ao cliente algo para fazer ao mesmo tempo que o lado do servidor tem algo a fazer. Como as bibliotecas do cliente precisam ser interpretadas - é melhor iniciar esse processo antes de fazer qualquer cálculo no servidor. A janela amortizada é o tempo que leva para o cliente processar o JS. Você obtém essa janela de graça, se você orquestrar um foguete de dois estágios.
Gleno
9

Na verdade, há um caso bastante sólido para usar o javascript embutido. Se o js for pequeno o suficiente (uma linha), eu prefiro o javascript inline devido a dois fatores:

  • Localidade . Não é necessário navegar em um arquivo externo para validar o comportamento de algum javascript
  • AJAX . Se você estiver atualizando alguma seção da página via AJAX, poderá perder todos os seus manipuladores de DOM (onclick, etc) para essa seção, dependendo de como os vinculou. Por exemplo, usando jQueryvocê pode usar os métodos liveou delegatepara contornar isso, mas acho que se o js for pequeno o suficiente, é preferível colocá-lo em linha.
Miguel Ping
fonte
5

Outro motivo pelo qual você deve sempre usar scripts externos é facilitar a transição para a CSP (Política de Segurança de Conteúdo) . Os padrões do CSP proíbem todos os scripts embutidos, tornando seu site mais resistente a ataques XSS.

Chiborg
fonte
4

Eu daria uma olhada no código necessário e o dividiria em quantos arquivos separados forem necessários. Todo arquivo js conteria apenas um "conjunto lógico" de funções etc., por exemplo. um arquivo para todas as funções relacionadas ao login.

Depois, durante o desenvolvimento do site em cada página html, você inclui apenas os necessários. Quando você entra no site, pode otimizar combinando todos os arquivos js necessários para uma página em um arquivo.

Gene
fonte
4

A única defesa que posso oferecer para javascipt embutido é que, ao usar visualizações fortemente tipadas com .net MVC, você pode consultar variáveis ​​c # no meio do javascript que achei úteis.

Austin_G
fonte
3

Três considerações:

  • De quanto código você precisa (às vezes as bibliotecas são um consumidor de primeira classe)?
  • Especificidade: este código é apenas funcional no contexto deste documento ou elemento específico?
  • Todo código dentro do documento tende a torná-lo mais longo e, portanto, mais lento. Além disso, as considerações sobre SEO tornam óbvio que você minimiza os scripts internos ...
roenving
fonte
2

Scripts externos também são mais fáceis de depurar usando o Firebug. Eu gosto de testar o meu JavaScript na unidade e ter todas as ajudas externas. Eu odeio ver JavaScript em código PHP e HTML, parece uma grande bagunça para mim.

Embreagem
fonte
2

Sobre o ponto de manter o JavaScript externo:

O ASP.NET 3.5SP1 recentemente introduziu a funcionalidade para criar um recurso de script composto (mesclar vários arquivos js em um). Outro benefício disso é quando a compactação do servidor da Web é ativada, o download de um arquivo um pouco maior terá uma taxa de compactação melhor do que muitos arquivos menores (também menos sobrecarga de http, ida e volta etc.). Eu acho que isso economiza na carga inicial da página e o cache do navegador é iniciado como mencionado acima.

À parte ASP.NET, esse screencast explica os benefícios em mais detalhes: http://www.asp.net/learn/3.5-SP1/video-296.aspx

Brendan Kowitz
fonte
2

Outro benefício oculto dos scripts externos é que você pode executá-los facilmente através de um verificador de sintaxe como o jslint . Isso pode salvá-lo de muitos bugs do IE6 de partir o coração e difíceis de encontrar.

Ken
fonte
1

No seu cenário, parece que escrever o material externo em um arquivo compartilhado entre as páginas seria bom para você. Eu concordo com tudo o que foi dito acima.

mattlant
fonte
1

Durante a prototipagem inicial, mantenha seu código em linha para o benefício de uma iteração rápida, mas certifique-se de torná-lo externo quando chegar à produção.

Atrevo-me a dizer que, se você não pode colocar todo o seu Javascript externamente, tem um design ruim em suas mãos e deve refatorar seus dados e scripts

Robert Gould
fonte
1

O Google incluiu tempos de carregamento nas medições de classificação de sua página; se você fizer muitas filas, levará mais tempo para as aranhas rastrearem sua página; isso poderá influenciar seu ranking de páginas, se você precisar incluir muito. em qualquer caso, estratégias diferentes podem influenciar sua classificação.

Kees Hessels
fonte
1

bem, acho que você deve usar inline ao criar sites de uma página, pois os scripts não precisarão ser compartilhados entre várias páginas

Zak Sheikh
fonte
-3

Sempre tente usar Js externos, pois js em linha é sempre difícil de manter.

Além disso, é profissionalmente necessário que você use js externos, já que a maioria dos desenvolvedores recomenda o uso de js externamente.

Eu mesmo uso js externos.

Daniel Puiu
fonte
2
Necessário profissionalmente? Por quê? Quem diz isso?
Siyah