Html5-boilerplate: solução de carregamento de script

Criado em 10 ago. 2010  ·  132Comentários  ·  Fonte: h5bp/html5-boilerplate




Este tópico de discussão está encerrado.

Foi divertido, mas as conversas mudaram para outro lugar por enquanto. Obrigado

Em agradecimento aos momentos divertidos que tivemos,

Aproveitar.





via labjs ou require.

meu arquivo load.js "boilerplate" tem LABjs embutido nele e, em seguida, usa-o para carregar jquery, GA e um arquivo site js. se ajudar, tenho um RequireJS + jQuery integrado em um arquivo: http://bit.ly/dAiqEG;)

também como isso atua na expectativa de um script de construção que concatena e minimiza todos os scripts? o carregamento do script deve ser uma opção?

javascript

Todos 132 comentários

kyle: " @paul_irish eu não concordo. http://bit.ly/9IfMMN cacheability (CDNs externos), download paralelo, script change-volatility ..."

james burke: " @paul_irish @fearphage @getify RequireJS tem uma ferramenta de construção para empacotar / minimizar scripts, então pode ter o melhor de ambos: dinâmico e pré-construído"

A maneira mais fácil para os desenvolvedores começarem com o carregamento do script seria provavelmente usando $ Lab.js, porque ele já está usando a sintaxe de encadeamento com a qual muitos usuários jQuery estão familiarizados.

Se eles estiverem construindo grandes aplicativos corporativos, eles sempre podem migrar para o require.js, se necessário.

atualmente, existem três técnicas principais de carregamento de script:

  1. HeadJS
  2. ControlJS
  3. LABjs

use ou não, qual usar é meio discutível: http://blog.getify.com/2010/12/on-script-loaders/

Também há requireJS e EnhanceJS apenas para que você saiba as alternativas para HeadJS ControlJS e LabJS . Até mesmo o Yahoo e o Google oferecem algo semelhante.

Com o lançamento do jQuery 1.5 e deferreds - http://www.erichynds.com/jquery/using-deferreds-in-jquery/ , Boris Moore os está utilizando no DeferJS, um novo projeto de carregador de script: https: // github. com / BorisMoore / DeferJS

Por padrão, o carregamento do script interrompe todos os outros downloads, portanto, fazer o download do modernizr no cabeçalho é ruim. O carregador embutido faz sentido, porque os carregadores podem baixar o script em paralelo e no modo sem bloqueio. Por exemplo, se você não precisa de todos os recursos do modernizr, pode embutir head.min.js que tem apenas 6kb ou uma compilação personalizada do modernizr (http://modernizr.github.com/Modernizr/2.0-beta/). CSS embutido às vezes também faz sentido. O Google usa inlining, eles inline css, js e 1x1 gifs vazios por meio de datauri.

O LabJS está se tornando amplamente usado e é uma boa solução - também pode ser incluído de forma assíncrona, portanto não precisa ser bloqueado.

http://blog.getify.com/2010/12/on-script-loaders/ é do autor

http://yepnopejs.com/ acabou de

yepnope também está integrado ao Modernizr como Modernizr.load .. http://modernizr.github.com/Modernizr/2.0-beta/

Portanto, provavelmente teremos um carregador de script em h5bp por meio de Modernizr.load em breve.

Eu não acho que fará 1.0, mas assim que eu levar o Modernizr para 1.8, vamos jogar isso no h5bp 1.1. Sim

Oi Paul

Transferi um site existente para usar seu H5BP e quero usar o carregador de script yepnope.js. É muito bom ver todos os bits e bots juntos como você fez.

O que você recomendaria usar no momento?

  1. Inclua yepnope.js junto com modernizer.js no topo da página
  2. Inclua-o na parte inferior da página, para carregar depois que o HTML terminar de carregar.
  3. Use a versão beta do modernizer.js
  4. Eu poderia concatenar yepnope.js com modernizer.js em um include.

Independentemente da melhor forma de incluí-lo, como você recomenda carregar os scripts com yepnope, js?

Acho que devemos fazer isso por aqui: https://github.com/paulirish/html5-boilerplate/blob/master/index.html#L52 e use yepnope para carregar a cópia CDN / Local do jQuery e nossos outros scripts.

Mas, você acha que é melhor usar um script externo para incluir ou renderizar um bloco de script dentro do html, que então carrega os scripts via yepnope.js?

Muito Obrigado.

Andy

Ah e outra coisa.

Como o yepnope pode carregar o css via, eu diria que é melhor incluir o css principal como faria normalmente e usar o yepnope para incluir apenas o css para correções específicas.

Por exemplo, incluindo alguns css que são aplicados apenas a versões mais antigas do IE.

hokapoka,

Use a versão beta do modernizr .. apenas inclua o que você precisa (e inclua Modernizr.load() ) e coloque isso no topo da página.

o código real para o substituto jquery com yepnope está em http://yepnopejs.com/

E sim, eu gosto da sua ideia de carga condicional do IE css.

tbh existe muita fé cega em torno do desempenho dos carregadores de script e não acho que estejamos prontos para dizer ESTE É O CAMINHO CERTO.

precisamos de mais pesquisas sobre tamanhos de arquivos, largura de banda e condições de rede que indicam recomendações inteligentes sobre o carregamento de scripts, mas agora o campo é incipiente e seríamos ingênuos em recomendar uma solução geral de carregamento de scripts.

tão.

fechando este tíquete e pedindo a qualquer um que se importe em fazer uma pesquisa abrangente e publicação necessária para tornar mais fácil para os desenvolvedores fazerem uma escolha inteligente sobre este

Pesquisei bastante sobre carga concat vs. paralela. Ainda assim, sem reservas, faço a recomendação de combinar todos os js em um arquivo primeiro, em seguida, dividi-lo em 2-3 ~ pedaços de tamanhos iguais e carregá-los em paralelo.

Adoraria poder levar minha pesquisa e torná-la ampla e em escala, para que fosse viável como "fato" nesta área. O problema é que tentei e tentei encontrar largura de banda de hospedagem onde não custasse muitos $$ para realmente executar os testes em escala e ainda não consegui encontrar essa provisão de hospedagem.

Se eu / nós pudermos resolver o problema de largura de banda para teste, tenho os testes que podem ser executados para descobrir se a teoria do carregamento paralelo é de fato viável (como acredito que seja).

@getify, o que você precisa em termos de equipamento de teste?

Posso fazer cerca de 1,5 TB a mais de dados do meu servidor pessoal do que estou usando atualmente. Eu tenho o Nginx instalado e ele pode lidar com algo em torno de 4 trilhões de quatrilhões de acessos por microssegundo. Não sinto que a tecnologia seja a barreira aqui.

Se estivermos preocupados com os locais, podemos falsificar a latência mais alta e / ou encontrar outras pessoas com um pouco de espaço extra em suas caixas.

BTW, tenho um pouco de problema com "fé cega".

É fácil, comprovável e quase sem dúvida verdadeiro que, se você tiver um site existente carregando muitos scripts com tags de script, o uso de um carregador de script paralelo (sem outras alterações) melhora o desempenho. Isso é verdade porque mesmo os navegadores mais recentes não podem (e nunca irão, eu não acho) liberar o carregamento de script do bloqueio do pronto para DOM. Portanto, mesmo no melhor caso de carregamento do navegador, se não houver outro benefício, acelerar drasticamente o pronto para DOM em um site é quase sempre uma vitória (para usuários e UX).

Sua declaração é um pouco falsa premissa porque assume que estamos tentando comparar, para cada site, o carregamento paralelo ao concat de script. A maioria dos sites na web não usa / não pode usar script-concat, então, na verdade, a comparação (para eles, a maioria) não é tão sutil e complicada como você imagina. Se eles não usarem / não puderem usar script-concat (por qualquer motivo), a comparação é simples: o carregamento paralelo é quase sempre uma vitória sobre as tags de script.

Se eles estão abertos para concat de script (ou já o usam), então sim, fica um pouco mais nuançado / complicado decidir se o carregamento paralelo pode ajudar ou não. Mas o script-concat também não é uma solução mágica que serve para todos, portanto, há muitos sites para os quais o carregamento paralelo continuará sendo a abordagem preferida e melhor.

Só porque alguns sites lidam com as nuances / complexidades de decidir entre carregamento paralelo vs. script-concat não significa que a maior (mais impactante) discussão de carregamento paralelo vs. tags de script deve ser perdida na mistura. O primeiro é difícil de provar, mas o último é quase um dado neste ponto.


Tudo isso é para dizer que, considerando todas as coisas, IMHO um clichê deve encorajar um padrão que tem o maior impacto em uma direção positiva. Se 80% dos sites na Internet hoje usam tags de script, a maioria dos quais se beneficiaria com a mudança de tags de script para carregamento paralelo, então o carregamento paralelo é uma coisa muito saudável de se sugerir como ponto de partida para o clichê.

É uma subseção muito menor (mas importante) desses sites que podem potencialmente obter ainda mais benefícios explorando concateamento de script versus carregamento paralelo. Mas um caso de uso minoritário não é o que deveria ser otimizado em um boilerplate.

Apenas meus poucos centavos.

@paulirish @slexaxton -

No que diz respeito às necessidades de largura de banda, estimei que para fazer com que 10.000 pessoas (o que eu sentia que era necessário para ser uma amostra precisa) executassem o teste uma vez (e muitas pessoas o executariam várias vezes, tenho certeza), seria cerca de 200 GB de largura de banda gastos. Para algumas pessoas, isso é uma gota no oceano. Para mim, 200 GB de largura de banda em alguns dias seria excessivo para os custos de hospedagem do meu servidor. Portanto, não busquei dimensionar os testes apenas por esse motivo.

Além disso, tenho mais de uma dúzia de variações desse teste que acho que precisamos explorar. Portanto, dezenas de vezes usando 100-200 GB de largura de banda cada teria um custo proibitivo para mim pagar a conta. Eu não queria começar por aquele caminho a menos que tivesse certeza de que tinha largura de banda suficiente para terminar a tarefa.

Eles são apenas arquivos estáticos, e os testes não requerem muitos usuários simultâneos, então não há nenhuma preocupação real sobre problemas de escala tradicionais como CPU, etc. Apenas largura de banda, isso é tudo.

Podemos levar o resto da discussão dos testes off-line e buscá-la por e-mail ou mensagem instantânea. Eu gostaria muito de finalmente dimensionar os testes e "resolver" esse problema. Isso está pairando no fundo do meu cérebro há quase um ano.

Posso fazer TB ilimitada no VPS do meu dreamhost, então isso não será um problema. agora estou fazendo 72 gb / dia e posso lidar com muito mais. :)

Eu concordo com paul, e acho que há um pouco de desinformação sobre como e quando os carregadores de script serão úteis para qualquer pessoa.

Seu primeiro parágrafo diz que é 'fácil', 'provável' e 'sem dúvida' que os carregadores de script melhoram o desempenho.

Fiz uma postulação semelhante a @jashkenas um tempo atrás, e ele e eu reunimos algumas páginas idênticas da melhor maneira que pudemos para tentar medir o desempenho de nossas _melhores_ técnicas. Ele é um fã de concat 100%, e eu tentei 2 técnicas diferentes de carregamento de script.

https://github.com/SlexAxton/AssetRace

O código está todo aí. Obviamente, não houve um grande público de teste, mas os resultados, na melhor das hipóteses, mostraram que este carregador de script tinha quase a mesma velocidade do método concat (seguindo as diretrizes de carregamento paralelo de 3 arquivos de tamanho semelhante) e, na pior das hipóteses, mostrou que o script- os carregadores variavam muito mais e geralmente eram mais lentos dentro de uma margem de erro. Sinta-se à vontade para fazer o fork e encontrar uma solução que supere o nosso ou os dois, mesmo que seja apenas na sua máquina em um navegador.

Quanto à "falsa premissa", porque h5bp assume que as pessoas concatam seus js. Este argumento é totalmente inválido porque h5bp oferece uma ferramenta de construção de script, completa com concat e minificação. Portanto, o argumento de que o carregamento paralelo é quase sempre uma vitória sobre várias tags de script pode ser verdadeiro, mas não é melhor do que o que o h5bp oferece atualmente. Esse é o contexto desta discussão.

Acho que o pior cenário são as pessoas pegando algo como yepnope ou lab.js e usando-o como uma tag de script polyfill. Isso com certeza vai resultar em um carregamento mais lento (de seus arquivos 19 JS e 34 CSS), bem como introduzir uma série de problemas de compatibilidade com versões anteriores e posteriores que eles desconhecem completamente.

Acho que com o espírito de dar às pessoas o padrão mais sensato, com desempenho e compatível para um _boilerplate_, uma ferramenta de construção vai muito além para garantir todos os três.

@slexaxton

... os resultados mostraram, na melhor das hipóteses, que este carregador de script tinha quase a mesma velocidade do método concat (seguindo as diretrizes de carregamento paralelo de 3 arquivos de tamanho semelhante) ...

Ficarei feliz em encontrar algum tempo para dar uma olhada nos testes que você montou. Tenho certeza que vocês sabem o que estão fazendo, então tenho certeza que seus testes são válidos e corretos.

OTOH, eu tenho muitas evidências contraditórias. Se eu alguma vez tivesse visto algo convincente para sugerir que o carregamento paralelo de script era um desperdício ou inútil para a maioria dos sites, eu já teria abandonado há muito tempo o coletor de tempo louco que é o LABjs.

Posso dizer com 100% de certeza que nunca, em 2 anos ajudando a colocar LABjs para as pessoas, encontrei uma situação em que LABjs fosse mais lento do que a alternativa de tag de script. Zero vezes isso já ocorreu _para mim_. Algumas vezes as pessoas disseram que não viam muitos benefícios. Houve algumas vezes em que as pessoas carregavam mais de 100 arquivos e, portanto, a sobrecarga absurda de tantas conexões eliminou todos os benefícios que poderiam ter visto de outra forma. Mas nunca ninguém me disse que o LABjs tornou seu site mais lento.

Eu mesmo ajudei literalmente mais de 50 sites diferentes a mudarem de tags de script para LABjs e, sem falhas, os sites viram melhorias de desempenho imediatamente. No início dos esforços, peguei uma amostra de talvez 7 ou 8 sites que eu tinha ajudado, e eles observaram coletivamente uma melhora média de cerca de 15% na velocidade de carregamento. Para os 4 ou 5 sites que gerencio, é claro que implementei LABjs e imediatamente vi até 3x a velocidade de carregamento.

Obviamente, quando o LABjs foi lançado pela primeira vez, os navegadores tinham o que fazer para carregar scripts em paralelo (apenas alguns faziam isso). Portanto, os ganhos foram enormes e visíveis. Agora, temos quase todos os navegadores fazendo carregamento paralelo, então os ganhos não são mais tão drásticos.

Mas o que é inegável é que todos os navegadores bloqueiam o evento pronto para DOM para o carregamento de tags de script. Eles _têm de_ por causa da possibilidade de encontrar document.write() . O carregamento paralelo do script está essencialmente dizendo "navegador, prometo que você não terá que lidar com document.write, então vá em frente e siga em frente com a página".

Dê uma olhada nos dois diagramas no slide 10 deste deck:

http://www.slideshare.net/shadedecho/the-once-and-future-script-loader-v2

Compare o posicionamento da linha azul (pronto para DOM). Essa é uma melhoria drástica no desempenho percebido (UX), mesmo se o tempo geral de carregamento da página (ou tempo para terminar o carregamento de todos os ativos) não for melhor.

... h5bp oferece uma ferramenta de construção de script ...

A suposição errada aqui é que só porque o h5bp oferece essa ferramenta, todos (ou até mesmo a maioria) dos usuários do h5bp podem usá-la. Mesmo que 100% dos usuários do h5bp _do_ o usem, isso não significa que se o h5bp fosse lançado para a cauda longa da internet, todos eles usariam essa ferramenta concat. Existem vários outros fatores que podem facilmente impedir alguém de usar isso. Existem _muito poucos_ motivos pelos quais alguém não pode deixar de usar tags de script para usar um carregador de script paralelo.

Como tal, o carregamento paralelo de scripts ainda oferece um apelo mais amplo para a cauda longa da Internet. Ainda é mais fácil para a maioria dos sites que não usam otimizações de carregamento de script, mudar do nada para algo, e que algo lhes oferece ganhos de desempenho. Poucos desses sites de cauda longa irão se esforçar (ou ter a habilidade de experimentar) ferramentas de criação de script automatizado em seus ambientes de hospedagem web não CDN de US $ 6 / mês baratos e compartilhados.

Acho que o pior cenário são as pessoas pegando algo como yepnope ou lab.js e usando-o como uma tag de script polyfill. Isso com certeza resultará em um carregamento mais lento ...

Eu não poderia discordar mais dessa afirmação. LABjs é projetado especificamente como um polyfill de tag de script. E as melhorias dos LABjs em relação às tags de script regulares (por enquanto, ignore o concat de script) estão bem estabelecidas e nunca foram seriamente refutadas. Se você tiver provas de que a maioria dos sites (ou mesmo muitos) que usam LABjs seria melhor voltar às tags de script, compartilhe.

Não há absolutamente nenhuma razão para que o carregamento de script paralelo resulte em um carregamento mais lento do que o que o navegador poderia realizar com tags de script. Isso não faz sentido. E, como estabeleci acima, as tags de script sempre bloquearão o pronto para DOM, o que não ocorre com o carregamento paralelo de scripts.

apresentam uma série de problemas de compatibilidade com versões anteriores e posteriores dos quais eles desconhecem completamente.

De que problemas de compatibilidade você está falando? A matriz de suporte de navegador da LABjs tem absolutamente a vasta maioria de todos os navegadores da web do planeta cobertos. O pequeno número de navegadores que ele invade é superado em muito pelo grande número de navegadores nos quais ele oferece benefícios claros.

O LABjs 1.x tinha um monte de hacks malucos, como pré-carregamento de cache, que de fato eram as principais preocupações para quebra de navegadores. O LABjs 2.x virou isso completamente de cabeça para baixo e agora usa abordagens confiáveis ​​e padronizadas para carregamento paralelo em todos os casos, voltando apenas para o hack do navegador de webkit mais antigo. Além disso, o LABjs 2.x já contém verificações para testes de recursos de técnicas de carregamento de script em breve (espero que em breve sejam padronizadas) como "pré-carregamento real".

Não posso falar definitivamente por nenhum outro carregador de script - sei que muitos ainda usam hacks - mas quanto aos LABjs, estou perplexo com a afirmação de que ele introduz problemas de compatibilidade com versões anteriores ou posteriores, pois acho que isso é claramente enganoso alegar.

para elaborar um pouco sobre por que pretendo que os LABjs sejam de fato uma tag de script polyfill ...

  1. navegadores mais antigos são claramente MUITO inferiores em lidar com o carregamento de tags de script que o carregamento paralelo pode manipular. foi nesses "navegadores mais antigos" (que eram os melhores / mais recentes quando o LABjs foi lançado há 2 anos) que vimos as melhorias no tempo de carregamento da página de ~ 3x. quase por definição, isso torna o LABjs um melhor script de tag polyfill, uma vez que traz um recurso (ou seja, desempenho de carregamento paralelo) para navegadores que não o suportam.
  2. os navegadores mais novos são obviamente muito melhores. mas eles não eliminaram completamente os benefícios dos carregadores de script. O chrome tão recentemente quanto a v12 (acho que finalmente foi corrigido na v13, ao que parece) ainda estava bloqueando o carregamento de imagens enquanto as tags de script terminavam de carregar. mesmo com o mais recente do IE, Firefox e Chrome, todos eles ainda bloqueiam o DOM pronto enquanto os scripts são carregados dinamicamente, porque todos eles ainda têm que assumir pessmisiticamente que document.write() pode estar à espreita.

Portanto, para os navegadores mais novos, o LABjs é um "polyfill" no sentido de que traz "carregamento de script de bloqueio não pronto para DOM" para o navegador de uma maneira que as tags de script não podem fazer. A única maneira possível de fazer isso em navegadores modernos sem um carregador de script paralelo seria usar tags de script com defer ( async obviamente não funcionará, pois não preserva a ordem) . No entanto, defer tem uma série de peculiaridades e seu suporte não é difundido o suficiente para ser uma solução viável (a alternativa para o não adiamento é o mau desempenho). Portanto, você poderia dizer que, no caso mais básico, LABjs é um polyfill para as características de desempenho da tag de script defer (embora não exatamente).

Honestamente, ainda acho que devemos solicitar padrões para um objeto de carregamento de script. Ter que criar uma tag de script de um tipo diferente de texto / javascript para acionar o cache (ou pior, usar uma tag de objeto ou um objeto de imagem ou qualquer outra versão exigida por um navegador popular) é uma tarefa difícil e o desempenho irá variar dependendo de muitas variáveis. Eu posso entender que ainda carregamos folhas de estilo usando inserção de nó dom (mas isso é apenas por causa da ordem), mas quando se trata de script, acho que não faz mais sentido (gostaria que o Google parasse de usar document.write na maioria dos seus scripts, mas isso é outra história).

Além disso, acho que estamos perdendo o maior ponto em relação aos carregadores de script: ser capaz de carregar o código js sob demanda em vez de carregar tudo antecipadamente (mesmo com tudo no cache, a análise e a inicialização levam tempo e podem ficar bem feio com uma quantidade não trivial de scripts concatenados). Ter algum tempo de espera após uma interação com a interface do usuário é muito menos problemático do que ter o navegador "travado", mesmo que um pouco na inicialização (o DOM pode estar pronto, mas de que adianta se o código para aprimorar a página e adicionar iteração ainda não foi executada: já percebeu como alguns sites carregam imediatamente e então algo desajeitado ocorre?).

Portanto, a medição estrita de desempenho é ótima e elegante, mas ainda acho que o desempenho percebido é o objetivo final ... e, infelizmente, é muito menos fácil de estimar / otimizar / calcular.

Isso é intenso.

@ jaubourg--

Honestamente, ainda acho que devemos solicitar padrões para um objeto de carregamento de script.

Há muitas petições em andamento a respeito de como os padrões / especificações e os navegadores podem nos fornecer uma tecnologia de carregamento de script melhor. A primeira grande vitória nesta categoria em anos foi o "assíncrono ordenado" ( async=false ) que foi adotado em fevereiro e agora está em todos os principais navegadores de lançamento atual (exceção: Opera em breve, e o IE10p2 tem )

O próximo debate, sobre o qual estou atualmente em discussões com Ian Hickson, é o que chamo de "pré-carregamento real". Na minha opinião, "pré-carregamento real" (que o IE já suporta desde a v4, btw) seria a coisa mais próxima de uma "bala de prata" que resolveria quase todos os cenários de carregamento de script de forma bastante trivial. Ainda estou bastante otimista de que veremos algo assim padronizado.

Veja este wiki para mais informações: http://wiki.whatwg.org/wiki/Script_Execution_Control

Ter que criar uma tag de script de um tipo diferente de text / javascript para acionar o cache (ou pior, use uma tag de objeto ou um objeto de imagem ou qualquer outra versão exigida por um navegador popular)

Isso é chamado de "pré-carregamento de cache" e é um hack feio e horrível. A maneira do LABjs não enfatiza isso agora a partir da v2 (usa-o apenas como um fallback para webkit mais antigo). Outros carregadores de script, infelizmente, ainda o usam como mecanismo de carregamento primário. Mas 90% da necessidade de "pré-carregamento de cache" pode ser resolvida com "async ordenado", que é padronizado e não é um hack, então carregadores de script bem comportados devem preferir isso em vez de "pré-carregamento de cache" agora.

Portanto, concordo que "pré-carregamento de cache" é uma droga, mas há maneiras muito melhores de usar document.createElement("script") que não envolvam tais hacks, então discordo que este seja um argumento contra continuar a depender do elemento Script do navegador para carregamento de script. Se pudermos obter um "pré-carregamento real", o elemento Script será tudo o que precisamos que seja. Eu honestamente acredito nisso.

Acho que estamos perdendo o principal ponto em relação aos carregadores de script aqui: ser capaz de carregar código js sob demanda

Concordo que esse é um benefício importante que os carregadores de script trazem. Mas é uma espécie de argumento discutível _este_ encadeamento, porque o pessoal do "concat de script" simplesmente não pode, sem o carregamento do script, resolver o caso de uso, portanto, não faz sentido "comparar" os dois. Você pode dizer como um proponente de "concat de script" "bom, não nos importamos com esse caso de uso", mas você não pode dizer "podemos atender melhor a esse caso de uso usando XYZ".

O desempenho percebido _é_ enorme e importante, eu concordo. O carregamento sob demanda é uma grande parte para fazer isso acontecer. O carregamento sob demanda também melhora o desempenho real real (não apenas a percepção) porque tende a fazer com que menos downloads sejam feitos se você baixar apenas o que é necessário (algumas visitas à página requerem 100% do código que você escreveu).

O desempenho percebido também é o motivo pelo qual defendo o argumento pronto para DOM acima. Porque a rapidez com que um usuário "sente" que pode interagir com uma página é _muito_ importante para o quão rápido eles pensam que a página é (independentemente de quão rápido ela realmente carregou). Isso é um fato estabelecido por muitas pesquisas de usuários.

Tenho que amar o apaixonado, longos comentários de @getify
Kyle ...

Se eu puder contribuir de alguma forma para a pesquisa, eu _adoro_.
A largura de banda (custos) não parece ser o problema, então @getify , o que você propõe no futuro?
Não hesite em me contatar por e-mail (aaron [arroba] aaronpeters [ponto] ou twitter (@aaronpeters)

@kyle

Sim, segui a discussão de "melhorias" da tag de script em relação ao pré-carregamento e simplesmente não aceito a abordagem "adicionar mais um atributo na tag de script" como uma abordagem viável. Eu vi o que isso fez com a especificação do xhr: muita complexidade em relação ao pequeno benefício que obtemos no final.

O que está claro é que praticamente só precisamos do comportamento de pré-carregamento ao fazer a inserção dinâmica (ou seja, já fazendo isso em javascript), então por que diabos ainda devemos usar a injeção de tag de script? Não é como se mantivéssemos a tag lá ou a usássemos como um nó DOM: é apenas um meio para um fim que não tem nada a ver com a estrutura do documento.

Eu ficaria muito mais confortável com algo nesse sentido:

window.loadScript( url, function( scriptObject ) {
    if ( !scriptObject.error ) {
        scriptObject.run();
    }
});

Isso faria maravilhas. É fácil "juntar" vários eventos de carregamento de script e, em seguida, executar esses scripts na ordem necessária. Também não implica a presença de um DOM, o que o torna ainda mais genérico. Eu gostaria que fugíssemos da injeção de tag de script o mais rápido possível. Além disso, é fácil fazer um polyfill usando os truques que todos conhecemos. Também é muito menos trabalhoso do que um sistema de requerimento completo (mas pode ser um bloco de construção para um sistema de requerimento que não se limita a navegadores).

Dito isso, concordo 100% com você sobre o desempenho percebido, só queria salientar porque o mantra "vamos compactar tudo juntos" está rapidamente se tornando algum tipo de crença que confunde as coisas demais para o meu gosto;)

fwiw, defer é compatível com IE4 +, Chrome, Safari e FF 3.5+. Não compatível com Opera.

Isso significa que ... 98,5% dos usuários já têm suporte para script@defer .

@getify

No entanto, defer tem uma série de peculiaridades,

detalhes, por favor? eu não vi nada sobre isso

Os scripts com adiamento são executados antes ou depois do disparo do evento pronto para DOM?

A ordem de execução é preservada em todos os navegadores?

Que tal a ordem exec e o acoplamento externo com scripts embutidos?

@ paulirish--

... 98,5% dos usuários já possuem suporte a script @ defer .

o suporte pode estar presente em tantos navegadores, mas isso não significa que seja confiável em tantos navegadores. foi isso que eu quis dizer. (Veja abaixo)

No entanto, adiar tem uma série de peculiaridades,

detalhes, por favor? eu não vi nada sobre isso

Deixe-me ver ... IIRC:

  1. o suporte de adiamento em elementos de script dinâmicos não é definido ou suportado em nenhum navegador ... só funciona para tags de script na marcação. isso significa que é completamente inútil para as técnicas e casos de uso "on-demand" ou "lazy-loading".
  2. Acredito que houve um caso em que, em alguns navegadores, os scripts adiados começavam a ser executados imediatamente antes do disparo do pronto para o DOM e, em outros, isso aconteceu imediatamente após o disparo do pronto para o DOM. Terá de fazer mais pesquisas para obter mais detalhes sobre isso.
  3. defer usado em uma tag de script que faz referência a um recurso externo se comportou de maneira diferente de defer especificado em uma tag de script com código embutido. Ou seja, não era possível garantir que funcionasse para adiar os dois tipos de script e fazê-los ainda rodar na ordem correta.
  4. defer em uma tag de script escrita por uma instrução document.write() diferia de uma tag de script na marcação com defer .

Não tenho muitos detalhes prontos na ponta dos dedos sobre essas questões. Lembro-me de cerca de 2 anos atrás (antes dos LABjs) tentando usar defer e encontrando tantos deles em testes entre navegadores que basicamente deixei de lado e não os visitei muito novamente desde então.


Devo também apontar que defer não é realmente a mesma coisa que os LABjs (e outros carregadores paralelos) fornecem. Eu disse isso acima com a ressalva de que é apenas meio parecido. Na verdade, o que o carregamento de script paralelo fornece (pelo menos, para a parte do LABjs), é "assíncrono ordenado", que não tem absolutamente nenhuma maneira de ser alcançado apenas por meio de marcação.

A diferença entre "assíncrono ordenado" e "adiar" é que "assíncrono ordenado" ainda começará a ser executado assim que o primeiro script solicitado terminar de carregar, enquanto "adiar" esperará até que o DOM esteja pronto antes de iniciar as execuções. Para uma página simples com pouca marcação e nenhuma outra chamada de marcação de bloqueio (como outras tags de script), essa diferença é pequena. Mas para uma página com muitos recursos, quando os scripts podem iniciar a execução pode ser drasticamente diferente.

Então, eu honestamente gostaria de não sair muito na tangente de defer , porque na realidade não é uma grande comparação com o que o carregamento paralelo de script fornece. Era apenas o exemplo mais próximo em marcação que eu poderia usar para descrever o comportamento de ordem de execução que eu estava obtendo. Eu provavelmente nem deveria ter levantado defer - só atrapalha a discussão.

Deixe-me reformular o que foi dito acima: "Para navegadores modernos, LABjs é um tipo de 'polyfill' para comportamento 'assíncrono ordenado', que não é possível optar por apenas marcação em nenhum navegador."

Eu gosto de "ordenado assíncrono", é uma boa frase.

Kyle> afaik, os scripts com defer serão executados _before_ onload, mesmo antes do domready.
Scripts com atributo assíncrono serão executados o mais rápido possível, e _always_ _before_ onload, mas não necessariamente antes de domready

@ aaronpeters--
Eu acho que você pode estar um pouco fora do caminho. É assim que eu entendo:

Scripts async (seja na marcação ou criados dinamicamente) serão executados o mais rápido possível, ou seja, a qualquer momento antes ou depois do pronto para o DOM. Em outras palavras, os scripts async devem esperar por nada (exceto a própria disponibilidade do mecanismo JS). No entanto, se eles forem solicitados antes de window.onload , então em quase todos os navegadores eles irão "segurar" o evento window.onload até que sejam carregados e executados. Acho que houve um caso documentado em que os scripts async não seguraram window.onload , apenas não se lembrando dos detalhes exatos.

defer por outro lado significa especificamente: espere até que o DOM esteja pronto. Além disso, há uma "fila" de todos os scripts com defer definidos neles, de modo que a fila não é processada até depois de estar pronto para o DOM. Isso significa que todos devem ser executados estritamente após o DOM pronto (ou, melhor, após o DOM está pronto e com análise finalizada, para ser exato). Mas eles podem ser atrasados ​​ainda mais (se o carregamento estiver lento). Porém, eles devem conter window.onload . Só me lembro de uma vaga memória passada que em algumas versões do IE a prática real dessa teoria era um pouco confusa.

@getify

Não queria atrapalhar este tópico ainda mais, então postei minha opinião sobre o pré-carregamento de script e sua proposta na página WHATWG aqui: http://jaubourg.net/driving-a-nail-with-a-screwdriver-the-way -rede

Scripts async (seja na marcação ou criados dinamicamente) serão executados o mais rápido possível, ou seja, a qualquer momento antes ou depois do pronto para o DOM. Em outras palavras, os scripts async devem esperar por nada (exceto a própria disponibilidade do mecanismo JS). No entanto, se eles forem solicitados antes de window.onload , então em quase todos os navegadores eles irão "segurar" o evento window.onload até que sejam carregados e executados.

Provavelmente, isso é mais fácil de entender quando você percebe que o JavaScript é de encadeamento único. (Eu sei que demorei um pouco ...)

Da mesma forma, se você usar setTimeout(fn, 0) para baixar recursos e eles entrarem na fila de download antes que onload acionado, o carregamento desses recursos (ainda) atrasará onload .

Acho que houve um caso documentado em que os scripts async não seguraram window.onload , apenas não se lembrando dos detalhes exatos.

Eu adoraria obter mais informações sobre isso. Por favor lembre-se! :)

Yay carregadores de script!

Um problema que tive ao implementá-los na rede de sites da AOL é lidar com condições de corrida. Por exemplo, carregar jQuery de forma assíncrona na cabeça e, em seguida, dizer um plugin jQuery no meio do documento entregue de forma assíncrona em uma postagem de blog.

Assim, iniciei meu próprio projeto de ciência do carregador de script (Boot.getJS) para lidar com isso. A ideia é fazer o download de todos os scripts em paralelo e executá-los na ordem em que estiverem, o mais rápido possível. Ele também suporta adiar para pronto ou carregamento e armazenamento em cache de scripts. A maioria das ideias são emprestadas (roubadas) por pessoas neste tópico, então, obrigado, pessoal. :)

Já que você estava discutindo benchmarks, decidi compartilhar uma página de teste que criei para entender as diferenças de desempenho, sintaxe e comportamento dos vários carregadores de script por aí, verifique aqui:

http://artzstudio.com/files/Boot/test/benchmarks/script.html

Para ver como vários carregadores se comportam, limpe o cache e observe as solicitações de rede e a hora final, bem como a ordem em que os scripts são executados.

Dave (@artzstudio), txs por compartilhar suas idéias e o link para sua página de teste.

Pergunta: por que você carrega LABjs na página '<script> tag in head'? Isso parece errado.

@artzstudio também, você está usando uma versão antiga do LABjs. Isso é intencional? Se sim, por quê?

@aaronpeters Na AOL, temos scripts como Omniture an Ad code (e mais) que precisam ir na cabeça, então é para onde vai a biblioteca do carregador em nosso caso de uso. Além disso, quando os scripts estão na parte inferior, há um problema FOUC em alguns de nossos widgets, portanto, quanto mais cedo as dependências forem carregadas (como o jQuery), melhor.

Não foi intencional, este teste tem alguns meses. Atualizarei as bibliotecas quando tiver oportunidade.

Para sua informação (espero que seja interessante / relevante), executei alguns testes no Webpagetest.org para ver o que acontece no IE8 ao carregar algumas das páginas de teste do @artzstudio .
Tags de script: http://www.webpagetest.org/result/110810_C7_752b756180e132f50a3ef065e9e059ca/
Yepnope: http://www.webpagetest.org/result/110810_8S_a53f4ed2e16179c328fc57c572e71076/
LABjs: http://www.webpagetest.org/result/110810_ZV_1ece92044799e52ed5199aed6b407133/
RequireJS: http://www.webpagetest.org/result/110810_Z3_a1537e41a0b0570286151859973d0cfa/

Vídeo comparando Yepnope e LABjs: http://www.webpagetest.org/video/view.php?id=110810_074cb94c1b04a7ac9bd6538ec3fdd8d3c07f842d

Algumas notas:

  • O Gzip está desativado no servidor, portanto, a forma como o tamanho de arquivo maior do RequireJS tem um impacto
  • Como mencionado antes, a página de tags de script carrega LABjs no HEAD (não faz sentido) e isso, é claro, tem um impacto

Por esses dois motivos criei um vídeo mostrando apenas Yepnope e LABjs.

O que acho interessante é que o tempo de início da renderização é muito melhor para LABjs. Por que é que? Adoraria entender melhor.

Observação final: Não estou postando isso com o objetivo de favorecer LABjs em vez de Yepnope ou algo assim. Apenas compartilhando dados ...

Desculpe, entendo o que você quis dizer sobre os LABjs no teste <script>. Corrigido agora, junto com uma atualização para LABjs.

@ artzstudio--

Assim, iniciei meu próprio projeto de ciência do carregador de script (Boot.getJS) para lidar com isso. A ideia é baixar todos os scripts em paralelo e executá-los em ordem, o mais rápido possível

Então, você estava ciente de que é _exatamente_ para que o LABjs foi projetado e faz muito bem (se é que posso dizer isso)? O que quero dizer é que você queria apenas uma API diferente ou que a funcionalidade de carregamento de script paralelo não era suficiente?


Em qualquer caso, por mais que adore me gabar dos LABjs, não acho que seja eficaz atolar este tópico com "olha, meu carregador de script é melhor no tipo X" de discussões. Essas discussões são úteis, mas em outro lugar.

No final, toda a tecnologia de carregador de script se resume a algumas idéias simples. Não importa que tipo de API sofisticada você coloque em cima dela, ou quais casos de uso você atenda, a tecnologia é a mesma. Deve haver 50 carregadores de script diferentes atualmente e, na verdade, nenhum deles oferece nada diferente em termos de tecnologia, apenas APIs diferentes. Portanto, comparar APIs é realmente uma discussão um tanto irrelevante.

O que devemos focar é se a tecnologia de carregamento de script de base que temos atualmente disponível em navegadores pode ser usada para melhorar o desempenho de carregamentos de página em comparação com apenas o uso de tags de script na marcação. Esta é uma premissa minha de que é absolutamente verdade, mas essa premissa foi questionada neste tópico. Portanto, a tarefa nº 1 é responder a essa pergunta.

Se descobrirmos que as tags de script são simplesmente melhores do que o carregamento de script, podemos simplesmente parar com toda essa loucura e encerrar todos os nossos projetos. Suspeito que não será o caso. ;-)

A tarefa nº 2 é descobrir de uma vez por todas se o script-concat é sempre melhor do que o carregamento paralelo. Novamente, minha premissa (e meus testes) mostram que concat'ar todos os arquivos em um é bom, mas então você tem que dividir aquele grande arquivo em 2-3 partes aproximadamente iguais e carregar paralelamente esses pedaços. Então, nós realmente precisamos testar essa teoria também.

Se descobrirmos que script-concat é sempre melhor, os carregadores de script ainda são úteis quando você considera que a maioria dos sites carrega scripts de mais de um local (jquery do Google CDN, google analytics do google, facebook / twitter / botões g + , etc). Portanto, precisaríamos então, como tarefa nº 3, determinar se concat é muito melhor que você deve hospedar suas próprias cópias de todos esses arquivos, concatenando-os junto com seu próprio código.

Kyle, você pode ver a fonte do meu exemplo e me dizer como eu instrumentaria o LabJS para executar todos os scripts na página em ordem (mesmo fora da cadeia)? Eu poderia muito bem ter interpretado mal a API (como disse o Paul, os carregadores de script são difíceis,% -).

Em 10 de agosto de 2011, às 9h09 ,

@ artzstudio--

Assim, iniciei meu próprio projeto de ciência do carregador de script (Boot.getJS) para lidar com isso. A ideia é baixar todos os scripts em paralelo e executá-los em ordem, o mais rápido possível

Então, você estava ciente de que é _exatamente_ para que o LABjs foi projetado e faz muito bem (se é que posso dizer isso)? O que quero dizer é que você queria apenas uma API diferente ou que a funcionalidade de carregamento de script paralelo não era suficiente?


Em qualquer caso, por mais que adore me gabar dos LABjs, não acho que seja eficaz atolar este tópico com "olha, meu carregador de script é melhor no tipo X" de discussões. Essas discussões são úteis, mas em outro lugar.

No final, toda a tecnologia de carregador de script se resume a algumas idéias simples. Não importa que tipo de API sofisticada você coloque em cima dela, ou quais casos de uso você atenda, a tecnologia é a mesma. Deve haver 50 carregadores de script diferentes atualmente e, na verdade, nenhum deles oferece nada diferente em termos de tecnologia, apenas APIs diferentes. Portanto, comparar APIs é realmente uma discussão um tanto irrelevante.

O que devemos focar é se a tecnologia de carregamento de script de base que temos atualmente disponível em navegadores pode ser usada para melhorar o desempenho de carregamentos de página em comparação com apenas o uso de tags de script na marcação. Esta é uma premissa minha de que é absolutamente verdade, mas essa premissa foi questionada neste tópico. Portanto, a tarefa nº 1 é responder a essa pergunta.

Se descobrirmos que as tags de script são simplesmente melhores do que o carregamento de script, podemos simplesmente parar com toda essa loucura e encerrar todos os nossos projetos. Suspeito que não será o caso. ;-)

A tarefa nº 2 é descobrir de uma vez por todas se o script-concat é sempre melhor do que o carregamento paralelo. Novamente, minha premissa (e meus testes) mostram que concat'ar todos os arquivos em um é bom, mas então você tem que dividir aquele grande arquivo em 2-3 partes aproximadamente iguais e carregar paralelamente esses pedaços. Então, nós realmente precisamos testar essa teoria também.

Se descobrirmos que script-concat é sempre melhor, os carregadores de script ainda são úteis quando você considera que a maioria dos sites carrega scripts de mais de um local (jquery do Google CDN, google analytics do google, facebook / twitter / botões g + , etc). Portanto, precisaríamos então, como tarefa nº 3, determinar se concat é muito melhor que você deve hospedar suas próprias cópias de todos esses arquivos, concatenando-os junto com seu próprio código.

Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/paulirish/html5-boilerplate/issues/28#issuecomment -1772315

Alguém poderia pensar que a física diz que concat é o melhor. Cada nova conexão HTTP é outro início lento + uma taxa de 100 ms em cenários de pior caso do CDN.

No entanto, a verdade sobre os documentos é que eles podem ser muito longos. Portanto, carregar um arquivo BFJS na cabeça pode retardar desnecessariamente a inicialização dos módulos. Carregar no final pode causar FOUC irritante. Pode haver implicações móveis para arquivos grandes: http://www.yuiblog.com/blog/2010/06/28/mobile-browser-cache-limits/

Acho que esse é o motivo por trás da regra "dividir a carga útil" de Souders (http://oreilly.com/server-administration/excerpts/9780596522315/splitting-the-initial-payload.html). Precisamos fazer o que é perceptivelmente mais rápido também.

E, infelizmente, isso se resume a uma espécie de resposta do tipo "depende", o que torna esse problema interessante o suficiente para nos manter entretidos.

Estou brincando com uma abordagem híbrida em que as chamadas getJS são enfileiradas e concatadas periodicamente em um intervalo de tempo definido, bem como concatenando em um nível de dependência de módulo (por exemplo, concatenar dependências RequireJS em vez de carregar uma de cada vez), tudo em tempo real no front-end.

É um experimento científico que, como você observou, esperançosamente não fará sentido em breve, mas é interessante mesmo assim.

@getify : Eu sei que isso é apenas uma chatice no desfile neste momento, mas ainda assim.

Se descobrirmos que as tags de script são simplesmente melhores do que o carregamento de script,
então podemos simplesmente parar com toda essa loucura e encerrar todos os nossos projetos.
Suspeito que não será o caso. ;-)

Eu poderia dizer muitas coisas sobre o óleo de cobra, mas uma demonstração funcionará tão bem:

http://jashkenas.s3.amazonaws.com/misc/snake-oil/labjs.html

http://jashkenas.s3.amazonaws.com/misc/snake-oil/vanilla.html

Essa é uma página com 100k de texto, 10 imagens e 171k de JavaScript. A versão vanilla usa um único arquivo minificado que inclui jQuery, jQuery-UI, Underscore e Backbone, bem como o arquivo timer.js que grava os resultados do tempo de carregamento. A versão LABjs carrega cada um dos 5 arquivos JavaScript (minimizados separadamente) usando LABjs.

Você descobrirá que não apenas não há benefício para a versão LAB, mas que as solicitações HTTP extras apenas prejudicam o desempenho de carregamento e têm que competir com outros ativos na página, como imagens. Mas tudo isso já foi dito muitas vezes antes ...

LABjs

Vanilla

Posso antecipar um contra-argumento sobre o carregamento de seus scripts em partes ... mas isso é inteiramente ortogonal à técnica de carregamento de scripts, então, por favor, deixe isso fora da discussão.

Por suposto, pare com a loucura.

@jashkenas Full, 100% ack. Os carregadores de script apenas adicionam sobrecarga, complicações e pontos de falha. Um único arquivo concatenado no servidor carrega rapidamente (est), tanto em termos de tempo de transferência puro quanto em termos de eficiência dos interpretadores JavaScript e, como bônus, o gzip funciona melhor se você tiver apenas um único arquivo.

Devo dizer que a versão LABjs _ às vezes_ carrega mais rápido no meu navegador (em comparação com a página inicial), mas não de forma consistente. Além disso, onload nem sempre dispara, o que parece ... estranho.

Sim, o gzipping oferece ainda mais vantagens gerais com menos solicitações HTTP.

E não se trata de dogma, não precisa ser um arquivo JS _único_ para todo o aplicativo - dois ou três com defer são adequados para um cache mais refinado, já que carregar mais tarde.

Algumas pesquisas da equipe do Google Page Speed:

http://pagespeed-velocity2011.appspot.com/#8 veja os slides 8-14, que tornam a discussão mais inconclusiva


Ainda estou interessado no atributo script @defer e acho que é um padrão básico sábio, a menos que você planeje mergulhar muitas horas / dias em testes de desempenho de suas próprias variações.

@miketaylr : Sim, atualize com a

Bem, labjs _sempre_ carrega mais rápido no meu navegador (Safari 5.1), mesmo com shift-refresh ou quando os elementos são armazenados em cache.

É claro que usar um carregador de script sem concatenar será mais lento do que uma tag de script concatenada. É por isso que as pessoas (YUI, requireJS) criaram carregadores de script que carregam arquivos concatenados e serviços que os concatenam quando solicitados (https://github.com/rgrove/combohandler).

Vamos, essa discussão não faz sentido. Os carregadores de script são para carregar scripts sob demanda, especialmente após a interação do usuário, por exemplo, carregando a lógica por trás do diálogo e validação de formulário ao clicar em um botão "logar".

Tenho uma leve suspeita de que @madrobby estão simplificando demais as coisas.
Steve sugere que o download paralelo tem vários benefícios para uma série de problemas de bloqueio e navegadores _ (sim, isso significa não-WebKit) _. Ele também menciona uma estratégia de carregar o JS mínimo necessário para tarefas dom-load e, em seguida, carregar o resto mais tarde, conforme necessário. Como as situações e as necessidades de desenvolvimento variam, não sei se um carregador de script pertence a um clichê _ (habilitado por padrão) _ mas eu não jogaria o bebê fora com a água do banho ainda.

Se não ficou claro no meu post original. Eu tendo a concordar (com jdalton) que existem alguns benefícios dos carregadores de script em ambientes altamente testados e específicos que requerem atenção especial. Não acho que seja um padrão apropriado.

Eu concordo com @jdalton : não existe um carregador de tamanho adequado. Eu pessoalmente uso diferentes carregadores de script, dependendo de minhas necessidades e projetos reais. Às vezes, algo simples como yepnope ou LabJS é bom, outras, RequireJS é uma dádiva de Deus. Não tenho certeza se um clichê tem que forçar um. É complicado porque a ideia seria que o clichê tornasse mais fácil mudar para um gerenciador de scripts ... então eu não jogaria o bebê fora com a água do banho apenas ainda também.

Além disso, @getify , fingir que todos os carregadores de script realmente usam a mesma tecnologia por baixo é uma declaração muito desinformada.

Por que vale a pena ...
isto

var script = document.createElement('script')
script.src = 'foo.js'
document.getElementsByTagName('head')[0].appendChild(script)

é melhor que isso

<script src="foo.js"></script>

pela razão principal de que não bloqueia. Portanto, as imagens subsequentes e os arquivos CSS precisarão esperar até que o arquivo seja baixado com a última versão. O primeiro é assíncrono - isso, todos devem saber, independentemente de você decidir usar um carregador de script ou não.

re: "fingir que todos os carregadores de script realmente usam a mesma tecnologia por baixo é uma declaração muito desinformada."

Se eles não estão fazendo da maneira acima, eles estão fazendo errado

Bem, para ser perfeitamente justo, usar appendChild caiu em desuso ...: D

No entanto, adicionei esse caso de teste ao AssetRace

https://github.com/SlexAxton/AssetRace/blob/master/asyncconcat.html

Isso torna o onload fire mais rápido, então _pode_ haver algum benefício percebido. Mas o tempo de chegada é quase o mesmo ...

@ded : Não estamos falando de grandes bloqueios incompetentes <script> em <head> aqui ... estamos falando de tags de script com defer ou async attribute, carregado no final do <body> , onde não há mais nada para bloquear.

@ jaubourg--

Além disso, @getify , fingir que todos os carregadores de script realmente usam a mesma tecnologia por baixo é uma declaração muito desinformada.

Esta é uma representação totalmente errônea do que eu queria chegar. Na verdade, a maioria dos carregadores de script NÃO está fazendo as coisas que eu acho que eles deveriam estar fazendo (e que os LABjs agora fazem) em termos de usar a melhor tecnologia. Meu ponto era, mesmo que todos eles usassem a melhor tecnologia, ainda há um limite finito para o que podemos fazer em termos de tecnologia. Tenho certeza de que não há carregadores por aí que usam alguma bala de prata mágica que o LABjs não conhece ou não usa. Você não pode fazer a luz ir mais rápido do que a velocidade da luz, não importa o que você faça ou como você mexe com os números.

Discutir sobre a tecnologia por baixo (por meio de dizer "ei, olhe minha API legal e melhor") é inútil. A melhor tecnologia em carregamento de script é uma quantidade finita conhecida (mesmo que muitos carregadores sejam irresponsáveis ​​e não a utilizem). Podemos pressionar por uma tecnologia melhor (que eu sou), mas debater quem tem a melhor API em seu carregador não ajuda em nada.


Este segmento realmente parece ter o maior objetivo em tentar determinar se as tags de script são boas o suficiente por si mesmas (com ou sem adiamento) ou se os carregadores de script ajudam a obter um melhor desempenho. Em segundo lugar, precisamos descobrir se concat é realmente o fim de tudo no carregamento do script.

Também é um ponto discutível (para este tópico) que os carregadores de script têm todos esses outros casos de uso que podem fazer, o que as tags de script de marcação não podem fazer (como carregamento on-demand / lento). Novamente, isso é basicamente um dado neste ponto, então tentar restabelecer esse fato é inútil.

NÃO VOCE

LOAD RAGE!

loaders make me rage

Veja a postagem original aqui.

Além disso, qualquer pessoa / pessoa ofendida por um pênis de desenho animado: bem-vindo à internet! Eu recomendo fortemente que você comece sua jornada aqui .

OK, criei 3 testes para ilustrar alguns pontos. Em primeiro lugar, tags de script manual (como linha de base):

http://labjs.com/dev/test_suite/test-script-tags.php

Observe que o DOMContentLoaded (também conhecido como "pronto para DOM") chega muito tarde, após a conclusão dos scripts. Isso é ruim. Embora o tempo real de carregamento da página possa ser o mesmo dos testes posteriores, o tempo de carregamento percebido da página sempre será muito mais lento se o pronto para DOM estiver sendo bloqueado (muitos sites aguardam até que estejam prontos para o DOM para anexar comportamentos de clique, aplicar melhorias baseadas em JS ao conteúdo, etc).

Agora, o que acontece é que usamos defer em nossas tags de script:

http://labjs.com/dev/test_suite/test-script-defer-tags.php

Bem, isso é bom, corrigimos o problema de atraso DOMContentLoaded, mas agora temos outro problema. O bloco de script embutido não funciona com defer . Ele é executado imediatamente. Opa. BTW, isso não é um bug, a especificação dita isso especificamente.

http://labjs.com/dev/test_suite/test-LABjs.php

O teste LABjs obtém basicamente os mesmos (ou melhores) números de desempenho em comparação com o teste defer , mas não falha em fazer com que o código embutido seja executado após a conclusão dos scripts.

Tente esses testes várias vezes em navegadores modernos (Chrome 13, FF5, etc). Para mim, os LABjs sempre tiveram o mesmo desempenho ou melhor no teste defer . Em todas as minhas tentativas, nunca vi LABjs ter um desempenho pior do que o teste de defer . Tente esses testes em navegadores mais antigos (como FF3.5 ou IE7), e você verá que o carregador de script começa a superar os outros testes em quantidades perceptíveis.

Mesmo que o teste LABjs tenha números semelhantes aos do teste defer nos navegadores mais novos, será um obstáculo se defer não puder ser usado para código defer ALL (só funciona para código que é carregado por meio de um arquivo externo). MUITOS sites carregam scripts e têm código embutido para ativar / iniciar o código que acabaram de carregar. defer não nos oferece solução para isso.

Portanto, defer não é adequado como uma tecnologia de "carregamento de script geral". A próxima melhor opção é um carregador de script.

@getify

Não se trata apenas de micro-otimizações ... e, SIM, API é importante e geralmente é uma boa indicação do tipo de limitações que a tecnologia subjacente tem, principalmente por causa dessas micro (ou mesmo macro) otimizações. Nem sempre se trata apenas de carregar scripts. Gerenciamento de dependências complexas, sandboxing adequado e modularidade real e real não é algo para se perder só porque você não tem nenhum interesse nisso. Adivinha? Na verdade, essas são as coisas de que as pessoas precisam e o desempenho de carregamento da página pode ser alcançado em um nível razoavelmente bom com tags de script estático.

Finalmente, tudo se resume a injeção de tag de script não sendo a ferramenta adequada para a tarefa: na verdade, nunca foi. É apenas um hack muito feio. Nesse sentido, você não está realmente pressionando por uma tecnologia melhor : você está pressionando por mais do mesmo, com novos tipos de advertências que nenhum de nós pode inferir ainda. Por favor, pense por um mero segundo e veja se ele finalmente clica.

O que é realmente irritante é que você se recusa a apresentar um único argumento a favor da injeção de tag de script em oposição a uma API javascript nativa adequada para carregamento de script. Você simplesmente ignora a coisa toda. Eu vou te poupar do problema: não há nenhum argumento nisso. Mas, heh, todos nós podemos ter um pouco de masturbação mental sobre os meandros do adiamento e assíncrono e sentir que somos os deuses do javascript, certo? Ou debata sobre otimizações de 50ms como se isso estivesse realmente ajudando alguém neste setor.

Se você finalmente decidir que mereço uma resposta inteligente (ao contrário de outro anúncio do LabJS), faça isso no meu blog e vamos manter este tópico em paz. Obrigada.

@jaubourg -
Eu li sua postagem profundamente na noite passada. Eu estava planejando escrever uma postagem no blog em resposta, em grande parte elogiando e cumprimentando você pelos bons pensamentos que você apresentou lá. Infelizmente, o que você está sugerindo já foi discutido COM EXTENSÃO pelos membros do tópico de discussão no W3C e no WHATWG. Você está muito atrasado para aquela festa.

Havia várias pessoas que apoiavam uma API de carregador totalmente nova e vários contra-argumentos importantes para explicar por que essa provavelmente não era a melhor maneira de fazer isso. Mais uma vez, estava planejando escrever uma resposta para você em uma postagem de blog cuidadosa e fundamentada, para ajudar a explicar tudo isso.

Que pena que você tem que ir e ser um idiota aqui. Agora me faz sentir que aquela postagem do blog racional será apenas uma perda de tempo. Você obviamente acha que eu sou um idiota e nunca considerei as coisas que você está tentando trazer à tona. Porque eu não passei a maior parte do ano passado absolutamente obcecado com a tecnologia do carregador de script e como obter as especificações e os navegadores para torná-lo melhor. Sim, sou um idiota. Eu claramente nunca pensei em nada além da tag de script antes.


Você aparentemente não ouviu as 15 vezes que eu disse que _este_ tópico tinha o melhor objetivo de se concentrar nas questões específicas que Paul Irish e Alex Sexton levantaram: defer bom o suficiente? o script-concat é melhor do que o carregamento paralelo?

Essas são as questões mais importantes.

Não o que a tecnologia de "carregador" subjacente é usada. Há um fórum diferente e melhor para discutir o que é a tecnologia de carregador subjacente. Eu entendo, você não gosta da tag de script. Multar. Vá passar dezenas de horas na lista W3C / WHATWG tentando fazer Ian e outros ouvirem você. Eles provavelmente vão apenas bocejar e dizer "nós já resolvemos isso, vá embora."

@getify : Criar testes de

Se você testar para confirmar um pré-equívoco ... seus testes sempre confirmarão esse equívoco. O debate nunca foi sobre 20 tags de script vs. 20 carregamentos de script LABjs. Trata-se de aparar, concatenar, reduzir, gzipar e carregar seu JavaScript de maneira inteligente no mínimo possível de solicitações HTTP e, em seguida, armazená-lo em cache.

Por um lado, temos uma abordagem confiável, com suporte de navegador e testada ao longo do tempo, que tem um desempenho comprovadamente melhor em páginas do mundo real; e, por outro lado, temos uma "tecnologia" hackeada que, no passado, quebrou todos os sites que a usavam após uma atualização do navegador, que apresenta desempenho comprovadamente pior em média e com uma variação muito maior de lentidão.

É uma escolha óbvia.

@ jashkenas--

Também sabemos que a execução de blocos de script embutidos antes dos scripts "adiados" não é um problema para sites reais.

Uhh ... Eu acho que você não fez view-source em cerca de 98% de todos os sites na internet, que na verdade usam blocos de script inline na marcação para executar / inicializar o código que carregaram anteriormente (bloqueio) chamada de tag de script.

Se @paulirish sugere que defer é bom o suficiente e que os carregadores de script não são necessários, então acho importante apontar porque, de fato, defer NÃO É bom o suficiente.

VOCÊ pode se preocupar apenas com os poucos sites de nicho que você controla, os quais você tem total capacidade de ser altamente otimizado sobre processos de construção, etc. Eu, por outro lado, me preocupo em ajudar a melhorar o desempenho nos sites de cauda longa da Internet, aqueles com meia dúzia de tags de script (alguns deles blocos de script embutidos!), onde usar meia dúzia de chamadas $LAB.script() provavelmente melhoraria o desempenho. Isso é o que LABjs sempre tratou. Só porque você não se preocupa com isso, não significa que não seja relevante.

O debate nunca foi sobre 20 tags de script vs. 20 carregamentos de script LABjs.

O debate neste tópico é se 3-4 tags de script (com ou sem defer ) têm desempenho pior, igual ou melhor do que 3-4 scripts carregados dinamicamente usando um carregador de script paralelo. Meus "testes ridículos de espantalho" têm, na verdade, a intenção de testar exatamente isso.

Na minha experiência, os carregadores de script economizam muitos milissegundos no tempo de carregamento da página. Mas acho que todos nós perdemos o ponto aqui. JavaScript tem alguns problemas maiores:

  • A falta de instruções de importação torna difícil organizar seu código de forma modular
  • Variáveis ​​globais colidindo, a menos que muita atenção seja dada ao namespacing cuidadoso de tudo.
  • Não há como ver claramente quais são as dependências de um script

Não uso o RequireJS porque carrega mais rápido, embora seja um bom efeito colateral. Eu o uso para organizar meu aplicativo JS em pequenos módulos, como faria no NodeJS. Cada módulo lista claramente suas dependências e usa o padrão sandbox para manter o namespace global limpo. Os módulos (e suas dependências) podem ser carregados antecipadamente, ou sob demanda (no clique do usuário, por exemplo), ou carregados lentamente. Você pode realmente ajustar seu desempenho com essas técnicas. E o RequireJS também vem com uma ferramenta de construção que combina e minimiza todas as dependências em um único (ou um punhado de) arquivo (s) pronto para gzip para implantação. Resolver esses três problemas é uma grande vitória para mim.

Posso ver por que as pessoas debatem sobre o uso de um carregador de script que não resolve esses problemas. Se o desempenho é o único ponto, e é discutível, então com certeza. Mas use um carregador de módulo AMD como RequireJS e o debate se torna irrelevante. Módulos são o futuro do JavaScript. Dave Herman, da Mozilla, está trabalhando com membros do conselho da Apple e do Google para adicionar módulos nativos à própria linguagem . Mas, enquanto isso, podemos obter todos os benefícios usando um carregador de módulo AMD. Não se trata apenas de desempenho.

@getify

Você não pode esperar que as pessoas o tratem de maneira diferente da que você trata os outros. Paternalista não é uma maneira inteligente de obter uma reação decente (e meu Deus, você está sendo paternalista) e, como eu disse em meu blog, não acho você um idiota, só acho que você está obcecado (o que você diz a propósito) e que isso prejudica seriamente o seu julgamento. Como eu disse em minha postagem no blog, não cabe ao W3C ou WHATWG lidar com esse problema, mas o próprio EcmaScript: este não é um problema de navegador, é um problema de linguagem. Agora, não responda se não quiser, é prerrogativa sua.

Talvez eu tenha sido duro, mas apenas defendo o que acredito.

Vou cancelar a inscrição neste tópico e comentar mais sobre ele. Desculpe por ter feito descarrilar coisas de @paulirish e @SlexAxton.

@getify

VOCÊ pode se preocupar apenas com os poucos sites de nicho que você controla e que possui
capacidade completa de ser altamente otimizado sobre os processos de construção, etc.
por outro lado, se preocupam em ajudar a melhorar o desempenho nos sites de cauda longa do
internet, aqueles com meia dúzia de tags de script (algumas delas script inline
blocos!), onde usar meia dúzia de chamadas $ LAB.script () provavelmente
melhorar o desempenho. Isso é o que LABjs sempre tratou. Só porque
não é com o que você se preocupa, não significa que não seja relevante.

Se o objetivo do LABjs é ajudar sites medíocres a carregar um pouco menos mal ... esse é um objetivo nobre, eu acho. Mas se você quer mesmo pegar um site de carregamento lento e carregá-lo o mais rápido possível - potencialmente literalmente segundos mais rápido do que os LABjs permitiriam, convém manter a mente aberta e reconhecer que mais fácil e menos frágil técnica também tem mais desempenho.

O debate neste tópico é sobre se 3-4 tags de script (com ou sem adiamento)
tem desempenho pior, igual ou melhor do que 3-4 scripts carregados dinamicamente usando
um carregador de script paralelo. Meus "testes ridículos de espantalho", na verdade, destinam-se a
teste exatamente isso.

O debate neste tópico é sobre como construir um site para carregar e executar seu JavaScript o mais rápido possível. Vender óleo de cobra para clientes e promovê-lo para desenvolvedores da web é um péssimo serviço para ambos.

A latência existe na Internet. Concatene, reduza e gzip seu JS e carregue-o na parte inferior da página com o mínimo de solicitações HTTP possível. Disse Nuff.

@ jashkenas--

Se o objetivo do LABjs é ajudar sites medíocres a carregar um pouco menos mal ... esse é um objetivo nobre, eu acho

Há centenas de sites que conheço pessoalmente nos últimos 2 anos que não fizeram nada além de substituir suas tags de script por chamadas de $LAB.script() e, em geral, todos viram um desempenho melhor (alguns drasticamente, outros apenas modestamente).

Foram escritos artigos (completamente independentes e não conectados a mim) focados em ajudar sites de vários setores (como comércio eletrônico, imobiliário, etc.) a obter um melhor desempenho (porque melhor desempenho significa mais conversões), onde esses artigos são recomendados para sites que eles substituem as tags de script por chamadas $ LAB, e muitas pessoas nesses tópicos de comentários responderam afirmativamente que isso os ajudou.

Esses artigos diziam "OK, o que você precisa fazer para obter mais desempenho é contratar um administrador de servidor que entenda gzip e possa instalar ruby ​​ou node.js para que você possa fazer alguns processos de compilação automatizados ..." essas pessoas ler esses artigos teria ficado vidrado e ido embora sem pensar mais no assunto. Mas eu gosto de acreditar que "Ei, substitua <script> por script ()" foi uma mensagem muito fácil para eles entenderem e se conectarem.

O que eu queria para o LABjs é uma solução simples que alguém possa facilmente usar para substituir suas tags de script sem pensar muito. Reconheço que, se você puder consultar pessoalmente um site e descobrir as melhores otimizações, poderá obter muito mais desempenho de muitos sites. Mas também reconheço que isso está muito além da minha capacidade como uma pessoa de fazer para a longa cauda da Internet e, da mesma forma, dizer a todos aqueles sites familiares "ei, vá buscar um sistema de compilação automatizado e certifique-se de que usa gzip" é como falando uma língua estranha para eles. OTOH, tem tido muito sucesso em dizer "Ei, pegue essas 3 tags de script e faça-as 3 chamadas de script (). Viu como foi fácil?"

Resumindo, minha abordagem com os LABjs era atingir o objetivo mais fácil.

Nada disso é para sugerir que abordagens mais sofisticadas para otimização não são possíveis - elas claramente são, e quando eu tenho a chance de consultar, eu definitivamente as exploro. É apenas para dizer que, para grande parte da web, é mais envolvente / complicada do que eles desejam ou são capazes de obter. E estou apenas tentando ajudar _aqueles_ sites a melhorar de uma forma que seja mais fácil para eles entenderem.

@ jashkenas--

potencialmente literalmente segundos mais rápido do que os LABjs permitiriam, então cabe a você manter a mente aberta e reconhecer que a técnica mais fácil e menos frágil também tem melhor desempenho.

Nunca houve qualquer evidência estabelecida para sugerir que LABjs está reduzindo significativamente a velocidade de qualquer site. Existem MUITAS evidências estabelecidas de que está ajudando muitos sites. Portanto, não acredito nisso - o que você está falando é uma premissa falsa assumindo fatos que não estão em evidência.

@paulirish encontrou uma postagem que aponta problemas com o atributo defer :
http://hacks.mozilla.org/2009/06/defer/

Vindo de uma perspectiva de desempenho móvel - como @jashkenas disse, é sempre melhor concatenar, fazer gzip e enviá-lo pela linha como um pacote do que ter várias solicitações http devido à latência incorrida por conexões de rede 3G.

Muitas pesquisas estão sendo feitas utilizando técnicas inlining onde você codifica imagens em bases64 em strings e, em seguida, as armazena como pares de chave: valor em localStorage apenas para reduzir as solicitações de http e alavancar o 'cache': http://channel9.msdn.com/Events / MIX / MIX11 / RES04 é uma ótima apresentação de James Mickens, da Microsoft Research.

Aqui está uma boa apresentação sobre o desempenho móvel com solicitações http e seus efeitos na experiência do usuário: http://davidbcalhoun.com/present/mobile-performance/

Eu trabalho no RequireJS e quero esclarecer o que o RequireJS pretende fazer:

1) Mostre o caminho para o código modular em JS que funciona bem em todos os lugares em que o JS é executado.
2) Carregar scripts.

A parte "carregar scripts" é uma parte necessária para atingir o primeiro objetivo. No dev, não é uma boa ideia apenas concatenar todos os seus scripts porque isso torna a depuração mais difícil, os números de linha não correspondem. Os carregadores de script também facilitam o uso de uma API JS para carregar o código sob demanda. Para aplicativos do tamanho de webmail, essa é uma parte necessária da história de desempenho. No entanto, concatenar os scripts em uma ou em um pequeno número de solicitações geralmente é a melhor opção de implantação.

Mas o objetivo de requirejs é ser o shim / polyfill / tudo para mostrar como criar e fazer referência a unidades de código modulares que podem ser compartilhadas com outras pessoas de uma forma que desencoraje os globais e incentive dependências explícitas.

Ele usa a API AMD que foi trabalhada com outras pessoas que fazem carregadores de script modulares (inclui testes de conformidade ), com o objetivo de ajudar a informar quaisquer discussões para um formato de módulo em JS. Essa abordagem, ao fazer implementações do mundo real e chegar a um acordo com outras pessoas sobre a API, é a forma como o progresso é feito.

Em particular, dada a natureza de rede do JS e sua relação com documentos / aplicativos da web, a API do plug-in do prototipagem dos módulos ES Harmony

Para o pessoal do desempenho :

  • Existem algumas opções para carregadores que suportam AMD ( curl , Dojo 1.7 , loadrunner , requirejs), mesmo um muito pequeno que pode ser usado para a otimização "todos os scripts em um arquivo JS" feita para implementação. Portanto, é possível obter um ótimo desempenho enquanto encoraja as melhores práticas de codificação - compartilhamento de código mais fácil, evitando globais, usando dependências explícitas.
  • O otimizador requirejs é executado muito rápido no Node e pode ser executado no Rhino. É uma ferramenta de linha de comando, mas o código de branch master mais recente exporta-o como um módulo utilizável no Node, portanto, por exemplo, pode ser executado por meio de um servidor http baseado em Node que pode fazer a construção em tempo real . Portanto, você sempre pode desenvolver no modo "download de um script sempre" se preferir, mas pode optar por deixar de fora um ou dois módulos desse arquivo otimizado, para que possa depurá-los facilmente.

No contexto deste tíquete : escolher um carregador compatível com AMD (não precisa ser obrigatório) se encaixa nos objetivos do boilerplate HTML: apontar o caminho para as melhores práticas, tanto em código quanto em desempenho. No entanto, eu aprecio que tentar trabalhar com um clichê HTML é uma coisa muito difícil de fazer, existem interesses conflitantes, alguns estilísticos, então eu aprecio não querer fazer uma recomendação nesta área neste momento.

Só quero deixar claro que o objetivo dos requirejs e carregadores que implementam a API AMD fornecem um benefício maior do que apenas carregar alguns scripts que descartam os globais e forçam o desenvolvedor a trabalhar na árvore de dependência completa, às vezes implícita. Esses objetivos são alcançados com soluções que possuem perfis de desempenho sólidos.

Para focar de novo ... comparando o teste defer com o teste LABjs ... (e ignorando o fato de que defer não funciona em blocos de script embutidos), alguém está vendo que o O teste LABjs tem um desempenho pior do que o teste defer ? Eu tentei em vários navegadores, e até mesmo no meu dispositivo móvel, e ainda vendo números quase iguais.

http://labjs.com/dev/test_suite/test-script-defer-tags.php

http://labjs.com/dev/test_suite/test-LABjs.php

@getify

Não tenho ideia por que ou como você pode otimizar isso, mas eu tenho, em minha máquina MacBook de 3 anos ou mais, uma diferença consistente de 3.000 entre os dois, o que favorece @defer .

No entanto, só testei com o Firefox.

@espadrine-- muito estranho. adoraria chegar ao fundo disso. com qual versão do Firefox você está testando? você pode me enviar uma captura de tela dos resultados?

Basta concatenar e reduzir todo o seu JS e CSS e incorporá-lo diretamente na sua página HTML e pronto. Solicitação HTTP única FTW! : P

Sério, existem muitos problemas maiores nos quais devemos nos concentrar nesta comunidade do que apenas como seu aplicativo irá carregar. Provavelmente, o método mais simples (tags de script na parte inferior) é provavelmente rápido o suficiente. Basta escrever ótimos aplicativos e lidar com o desempenho de carregamento no final. Fazer qualquer outra coisa é otimizar prematuramente.

Existe um consenso geral entre as pessoas neste tópico de que a AMD deve ser o padrão ouro para a organização de código JS? Na verdade, não vi outras opções, mas concordo que o Boilerplate seria um ótimo começo para configurar as pessoas corretamente na organização do código.

Canal de atualização do Firefox UX 8.0a1 (07/08/2011).

defer
LABjs

Novamente, não tenho ideia do porquê, e isso provavelmente é muito específico. LABjs provavelmente é muito bom com navegadores legados.

Por favor, não use a página de teste do @getify para nada mais do que rir. Citar:

<script defer src = "http://labjs.xhr.me/dev/test_suite/testscript1.php?_=4911710&delay=5"> <script defer src = "http://labjs.xhr.me/dev/test_suite /testscript2.php? _ = 6146431 & delay = 3 "> <script defer src =" http://labjs.xhr.me/dev/test_suite/testscript3.php?_=9499116&delay=1 ">

@getify , se você quiser fazer um teste real, sinta-se à vontade para fazer um fork do repositório AssetRace da @SlexAxton e adicionar uma versão LABjs ... ou fazer uma página de teste que use _real_ de arquivos JavaScript, com latências reais.

Além disso, certifique-se de concatenar o JS para uma única tag de script - defer ou não. O ponto é que o mesmo conteúdo servido em 1 solicitação HTTP supera o mesmo conteúdo servido em 10 solicitações HTTP.

Nunca houve qualquer evidência estabelecida para sugerir que LABjs é significativamente
desacelerar todos os sites. Existem MUITAS evidências estabelecidas de que está ajudando muito
de sites. Então, eu não acredito nisso - o que você está falando é uma premissa falsa, supondo
fatos não evidentes.

O que foi demonstrado acima é que o LABjs está, de fato, reduzindo significativamente a velocidade dos sites, ao fazer seu JS competir em muitas solicitações HTTP com suas imagens, CSS e outros ativos. @getify : Eu adoraria ver um link para um site que você acha que demonstrou muito com a sua conversão para LABjs. Talvez possamos baixar uma cópia disso e usá-la como um caso de teste que você respeitará.

Para registro, acho que seria sensato obter mais algumas imagens na página de teste de repositório AssetRace. Mas certamente é uma boa linha de base agora.

@artzstudio organizar seu JS com um carregador AMD é de fato o padrão ouro, pelo menos até que os módulos do Harmony sejam finalizados e amplamente suportados. Em seguida, haverá um caminho claro de migração dos módulos AMD para os módulos nativos.

Módulos AMD sendo o padrão ouro é certamente uma opinião (que eu posso compartilhar). No entanto, existem muitas pessoas inteligentes (Yehuda Katz e Dan Webb vêm à mente) que não gostam e oferecem outras soluções.

O loadrunner de @danwrong pode fazer as duas coisas, se for sua também: https://github.com/danwrong/loadrunner

Algumas coisas muito boas aí. Potencialmente um pouco mais prático para pessoas que não são JS também. Eu gosto de módulos AMD para minhas coisas, mas nem todo mundo quer perder tempo convertendo cada versão das bibliotecas que usa em módulos.

Eu sei que @strobecorp está trabalhando em sua própria solução que não requer muitos códigos extras que os módulos AMD requerem.

Embora eu adorasse que a AMD fosse o padrão, provavelmente não é sensato do ponto de vista de multi-biblioteca / newb, tanto quanto eu gostaria que fosse.

@ jashkenas--

Por favor, não use a página de teste do @getify para nada mais do que rir.

Se você não pode ser civilizado, não desejo discutir mais nada com você. Estou agindo de boa fé. Eu apreciaria um pouco de decência comum.

@getify , se você quiser fazer um teste real

Com certeza gostaria que você explicasse por que o que estou fazendo é tão louco, ridículo e inválido. Adotei a abordagem diretamente de Steve Souders, que (em sua grande experiência e sabedoria) sugeriu em todos os seus testes que você usasse o tempo do servidor para controlar os scripts, reduzindo a quantidade de variância em seus testes. Isso é exatamente o que estou fazendo.

Um teste mais controlado é um teste de linha de base válido. Essa é uma prática científica estabelecida. Isso não significa que os testes do mundo real também não sejam úteis, mas também não significa que você pode me atacar e dizer "ria dele, que idiota, porque ele faz os testes de maneira diferente que eu acho que eles Deve ser feito."

sinta-se à vontade para fazer um fork do repositório AssetRace da @SlexAxton e adicionar uma versão do LABjs

Fico feliz em fazer isso. Mas não porque concordo que meus outros testes são inválidos. Se você tiver alguns argumentos razoáveis ​​e sensatos sobre por que minha configuração de teste não é válida, por favor, compartilhe. Mas pare de ser um idiota sobre isso.

@ jashkenas--

O ponto é que o mesmo conteúdo servido em 1 solicitação HTTP supera o mesmo conteúdo servido em 10 solicitações HTTP.

Eu sei que você (e outros) continuam reclamando aqui sobre como essa discussão deveria ser sobre concat vs. não-concat. Se você leu muito antes no tópico, imaginei que havia duas questões que precisavam ser abordadas. Os dois problemas são, no que me diz respeito, ortogonais. A primeira é se as tags de script na marcação podem ser tão boas (ou melhores) do que os elementos de script dinâmicos usados ​​em um carregador de script paralelo. Essa pergunta é o que ainda estou tentando resolver com meus testes.

A segunda questão, que ainda não respondemos, é se o script-concat é sempre melhor. Sei que você já está convencido disso, mas tenho contra-evidências para sugerir que não é tão simples. Essa questão também precisa ser testada exaustivamente. Mas não é o que estou tentando descobrir agora neste tópico.

Ao continuar a insistir que o seu jeito é o melhor, você apenas torna todo o debate menos agradável de fazer parte. Tudo o que estou tentando fazer é estabelecer metodicamente algumas evidências para cada uma dessas duas questões principais, para que possamos parar de adivinhar e ficar mais informados. Por que você não pode ajudar com isso, em vez de tentar ser um idiota porque discorda de mim?

Com relação ao teste defer versus o teste LABjs, acabei de fazer uma captura de screencast rápida do teste dos dois frente a frente no IE9, FF8 (noturno) e Chrome15 (canário).

http://www.screenr.com/icxs

Para responder à pergunta anterior de defer quirks, observe como "DOMContentLoaded" se comporta no IE, Chrome e Firefox no teste defer .

No IE9 e Chrome15, o evento DOMContentLoaded é retido (bloqueado) e não disparado até que os scripts sejam executados. No FF, entretanto, o evento DOMContentLoaded não é retido, ele é acionado imediatamente e os scripts começam a ser executados depois dele. Essa é uma grande inconsistência entre os navegadores modernos e uma das razões pelas quais não acho que defer seja suficiente.

Pelo que posso dizer com a leitura das especificações, não tenho certeza de qual comportamento é o correto. Mas eu sei que é claramente peculiar e inconsistente entre os navegadores.

@getify Não estou tentando ser um idiota. Sinceramente, peço desculpas por ter magoado seus sentimentos.

Naturalmente, o que você vê como discurso retórico, eu vejo como o ponto da discussão ... e o que eu vejo como óleo de cobra, você vê como um passo útil à frente.

As duas questões são de fato ortogonais (linguagem que usei em minha postagem original).

A primeira é se as tags de script na marcação podem ser tão boas (ou melhores) do que
elementos de script dinâmico usados ​​em um carregador de script paralelo.

Estamos totalmente de acordo sobre este assunto - não importa. É claro que o carregamento paralelo será mais rápido do que o carregamento sequencial para mais de um script. E, claro, fazer isso de forma não bloqueadora, seja no final da tag <body> , ou com defer , ou com um carregador de script, será melhor do que bloquear no <head> .

Mas isso não acerta o ponto. Colocar tags de script sequenciais é um espantalho para comparação, porque ninguém que se preocupa com o desempenho de seu JavaScript usaria essa abordagem. Adivinhe o que também é mais rápido do que as tags de script sequencial? _Nada_.

A segunda questão, que ainda não chegamos, é se
script-concat é sempre melhor.

Nós "chegamos" a esta questão. Na verdade, é a pergunta de

Essa questão também precisa ser testada exaustivamente.

Para me repetir, aqui está um caso de teste (razoável). Os mesmos 5 scripts do mundo real, carregando em uma página de tamanho médio com outros ativos presentes, um usando as práticas recomendadas de LABjs para garantir a ordem de carregamento e o outro usando um único script concatenado:

http://jashkenas.s3.amazonaws.com/misc/snake-oil/labjs.html

http://jashkenas.s3.amazonaws.com/misc/snake-oil/vanilla.html

Se você tiver outro caso de teste que gostaria de examinar, ou um site do mundo real usando LABjs que gostaria de experimentar, compartilhe-o.

@SlexAxton Obrigado. Eu ficaria curioso para ouvir a opinião de Yehuda sobre isso e outras opiniões fortes (além de ser muito difícil de refatorar). Eu encontrei isso, mas não a conversa.

Para esclarecer o comentário de @geddesign : a partir de hoje , parece que os módulos AMD podem ser convertidos com bastante facilidade em módulos de harmonia, mas essa proposta de módulos de harmonia que considero ainda estar em desenvolvimento, pode mudar mais tarde. Ainda não passou por um teste de implementação rigoroso, mas está começando a ganhar alguns pontos. No lado positivo, os carregadores + plug-ins do carregador da AMD podem dar um feedback sólido para experimentar algumas das idéias de harmonia.

Para o comentário de @SlexAxton :

Para loadrunner: não está claro para mim que a sintaxe seja melhor, apenas diferente. Ele suporta AMD, então ainda funciona.

Para strobe: ainda não vi o código deles. Eles parecem bastante voltados para dentro, embora eu aprecie o trabalho que Yehuda fez para abrir esse desenvolvimento. Alex, se você tiver dicas sobre o que eles estão pensando, eu gostaria de recebê-las.

Se a abordagem vai permitir dependências aninhadas (que são necessárias para amplo compartilhamento de código), você precisa de uma sintaxe que:

  • dá um nome a uma unidade de código
  • uma maneira de especificar dependências
  • um wrapper de função em torno desse código para garantir que ele não seja executado até que as dependências estejam prontas. Ou sempre ordene um build ou acesso XHR, que não é escalonável em todo o espectro de desenvolvimento JS.

Isso é o que a AMD oferece, e a sintaxe é a mais leve possível. Qualquer outra coisa é apenas brigar por nomes e possivelmente alguns tipos de pontuação. Em algum momento, algo apenas precisa ser escolhido e, até agora, não ouvi de Dan Webb ou Yehuda sobre fraquezas estruturais que tornam a AMD insustentável. Alguns carregadores AMD, como o requirejs, podem carregar apenas scripts regulares, eles não precisam ser módulos.

É muito fácil pensar na sintaxe do código, particularmente para módulos, e posso apreciar que cada um tem suas próprias preferências pessoais. No entanto, a AMD tem um histórico bastante profundo de trabalho árduo para conseguir algum tipo de acordo e, mais importante, código real e implantação para fazer o backup. Sinto que agora recai sobre os outros a responsabilidade de ser muito claro e claro por que a AMD não é uma boa opção (este tíquete não é o lugar para isso, sinta-se à vontade para entrar em contato comigo fora da lista ou usar a lista amd-implement ) .

Mas agradeço a opinião de

@SlexAxton estou com você. Meu próprio código é AMD o tempo todo. Embora eu deseje que todos escrevam módulos em vez de scripts, felizmente o RequireJS pode carregar scripts simples, bem como módulos.

Se você está se referindo aos modelos de handlebars.js de Yehuda, eles funcionam extremamente bem com RequireJS. Especialmente se você escrever um plugin que compila / armazena em cache o modelo e retorna sua função de modelo.

define(['tmpl!navigation.html'], function(nav){
   $('body').append(nav(data));
});

No entanto, discordo desta afirmação:

Embora eu adorasse que a AMD fosse o padrão, provavelmente não é sensato do ponto de vista de multi-biblioteca / newb, tanto quanto eu gostaria que fosse.

Newbs precisa da estrutura limpa que a AMD fornece ainda mais do que um desenvolvedor experiente, pois eles são mais propensos a colisões de variáveis ​​globais, organização de código terrível que leva a enormes arquivos JS bagunçados que ninguém quer mexer por medo de ter que lidar com conflitos de mesclagem, etc. As bibliotecas se beneficiam enormemente com os módulos, e é por isso que os próximos Dojo 1.7 e Mootools 2.0 estão mudando para AMD. Espero que o jQuery aceite - uma de suas maiores reclamações é que é "tudo ou nada". Você não pode usar sua excelente manipulação de DOM sem também carregar sua animação, ajax, eventos, etc. na página. Então, sim, a AMD é uma situação em que todos ganham. Se o HTML5 Boilerplate deseja indicar às pessoas as melhores práticas, seria uma pena deixar de fora a AMD. Ele resolve muitos dos problemas do JavaScript com elegância.

Para ser claro. Eu concordo. Eu gostaria que eles usassem exigir todo o caminho.

Eu só não acho que eles vão.

Não acho que as pessoas ainda percebam que AMD é uma palavra da moda, uma "coisa" que todo desenvolvedor sério precisa saber. Depois de fazer isso, eles vão querer dizer a seus chefes e em entrevistas futuras que eles sabem sobre isso e vão usá-lo.

Se todos nós fizermos nossa parte e dissermos "veja, é fácil, e melhor e importante" e transformarmos isso em uma palavra da moda, os rebanhos seguirão por causa de suas carreiras.

@ jashkenas--

A primeira é se as tags de script na marcação podem ser tão boas (ou melhores) do que os elementos de script dinâmicos usados ​​em um carregador de script paralelo.

Estamos totalmente de acordo sobre este assunto - não importa.

Na verdade, comecei minha participação neste tópico assumindo que todos concordavam que o carregamento de elemento de script dinâmico levaria a um melhor desempenho do que as tags de script. Mas tanto @paulirish quanto questionaram essa suposição neste _neste_ tópico.

@paulirish sugeriu que defer é uma maneira suficiente de tornar a tag de script simples e tão boa (ou melhor) do que a alternativa de carregamento de elemento de script dinâmico. Não concordo que defer seja suficiente e já estabeleci vários motivos.

Portanto, acho que é válido termos examinado a primeira questão e explorado se defer era melhor do que os carregadores de script. Pode haver alguns casos limitados em que você pode se safar com defer , mas no que diz respeito ao caso generalizado, os carregadores de script tratam / normalizam todas as peculiaridades, enquanto defer expõe você a esses problemas.

Ainda não tenho certeza se todos veem ou concordam com o motivo pelo qual defer não é suficiente.

Para me repetir, aqui está um caso de teste (razoável). Os mesmos 5 scripts do mundo real, carregando em uma página de tamanho médio com outros ativos presentes, um usando as práticas recomendadas de LABjs para garantir a ordem de carregamento e o outro usando um único script concatenado:

Esta é a sua premissa de teste falsa (e de outros). Nunca, jamais, afirmei que carregar 5 scripts em vez de 1 seria mais rápido. Nunca. Sempre. Posso ser mais claro? A premissa nunca foi 5 vs. 1.

O primeiro teste foi testar 3 tags de script vs 3 chamadas script() , porque esse é um teste justo. E eu acho que o vídeo e os testes ilustram que o carregamento do script, nesse cenário, é benéfico.

A segunda, e muito mais complexa para testar a questão, é se há alguma maneira de melhorar o desempenho de um site que já está carregando todo o seu JS em um arquivo. A maioria das pessoas diz que é impossível melhorar isso. Discordo.

NOTA: a razão desta questão ser ortogonal é que você pode carregar esse arquivo concat único com uma tag de script ou usando o carregamento dinâmico do tipo document.createElement("script") . De qualquer maneira, a questão de um único arquivo concat é uma questão válida, mas separada de se as tags de script ou o carregamento de script dinâmico são melhores.

O que você me ouviu dizer várias vezes neste tópico e também em muitos outros contextos (incluindo todas as minhas conferências falando sobre o assunto, postagens de blog, etc), é que eu acho que é possível que você possa melhorar o concat de arquivo JS único abordagem "chunking" (que é dividir o grande arquivo concat) em 2 ou 3 chunks (no máximo). Se os pedaços forem de tamanho ~ igual e carregados em paralelo, é possível que a página carregue mais rápido, mesmo com a sobrecarga HTTP extra, por causa da conexão "Keep-Alive", efeito de carregamento paralelo, etc.

Na verdade, eu estava escrevendo sobre este tópico há muito tempo, em novembro de 2009, logo após o primeiro lançamento do LABjs: http://blog.getify.com/2009/11/labjs-why-not-just-concat/

Naquela postagem do blog, e desde então, eu disse que SE você estiver em uma posição (nem todo mundo está ... na verdade, a maior parte da web não está) de usar processos de construção para concatenar, você deve fazer tão. Período. Sempre. Sempre concate arquivos de 10 a 20 arquivos locais para muito menos.

MAS, eu também digo que, uma vez que você tenha aquele único arquivo concat, também pode ser benéfico tentar carregar seu único arquivo em 2-3 partes, carregadas em paralelo (usando um carregador de script).

Por que isso pode ser melhor? Eu esbocei naquele post do blog, mas resumindo:

  1. efeito de carregamento paralelo é real. pergunte aos usuários de bit-torrent sobre isso. a sobrecarga de HTTP também é real e age para neutralizar e eliminar esse benefício. Mas isso não significa que seja impossível se beneficiar. Usando o Keep-Alive de conexão, é possível obter 2 ou 3 conexões simultâneas (sem 2-3 penalidades de sobrecarga de conexão total) e carregar seu código em um período de tempo mais curto. Será 1/3 do tempo (60-70% mais rápido) se você carregá-lo em 3 partes? Não. Absolutamente não. Mas pode ser 20-30% mais rápido.
  2. Servir todo o seu código em um único arquivo evita que você faça cabeçalhos de cache diferentes para códigos de vida útil diferentes. Por exemplo, jquery é muito estável e nunca precisa ser baixado novamente. mas seu código centrado em UX em seu site pode ser muito volátil (você pode ajustá-lo uma vez por semana ou mais). Fazer cache de cabeçalhos curtos no arquivo concat único é estúpido, porque força novos downloads mais frequentes de código estável desnecessariamente. Fazer longos cabeçalhos de cache no arquivo concat único também é estúpido, porque força você a invalidar o arquivo em cache (parâmetro de quebra de cache, etc) e forçar um novo download completo de todo o arquivo, quando você apenas ajusta um único byte de seu código mais volátil. Portanto, dividir seu grande arquivo concat em 2 blocos, um para o código estável e outro para o código volátil, permite que você tenha cabeçalhos de cache diferentes para cada bloco. Isso torna o uso do cache mais eficaz e leva a um desempenho potencialmente melhor com o passar do tempo, conforme os usuários visitam seu site novamente.
  3. Estudos mostraram que, em média, uma única visualização de página usa muito menos do que 100% do JS que é carregado na página (algumas estimativas colocam em torno de 20-30% do código). Carregar todo o seu código de uma vez, de uma só vez, no início do carregamento da página, está congestionando a linha desnecessariamente para empurrar 70-80% do arquivo que não é necessário então (e pode "nunca" ser necessário). Se você tem seu código em 2 blocos (um que é o código mais crítico e outro que é o código menos crítico), e carrega o primeiro fragmento imediatamente e carrega o segundo fragmento alguns segundos após o carregamento da página, você pode liberar o tubo para as imagens / css e conteúdo muito mais importantes. Em essência, a fragmentação permite que você priorize seu código.

Resumindo ... no tópico concat vs. paralelo ... Eu _sempre_ digo às pessoas: ambos.

@getify bem dito.

Os LABjs de Kyle têm meu apoio.
Como consultor que ajuda sites a melhorar o desempenho, tenho visto LABjs funcionar bem muitas vezes.
Não só melhorou o desempenho significativamente (não apenas 100 ms, mas 1+ seg), mas também os desenvolvedores gostaram.
Fácil de entender, fácil de implementar.

E vou aproveitar esta oportunidade para dizer publicamente "Obrigado Kyle, pelo grande apoio no LABjs. Você superou minhas expectativas várias vezes."

Usando o Keep-Alive de conexão, é possível obter 2 ou 3 conexões simultâneas (sem 2-3 penalidades de sobrecarga de conexão total)

O HTTP não multiplica / intercala as respostas, então você não pode fazer downloads paralelos sem abrir várias conexões primeiro. O caso ideal de conexão persistente e em pipeline é igual ao download contíguo de um único arquivo (+ alguns cabeçalhos).

@ pornel--

Eu vi em primeira mão e validei que os navegadores podem abrir várias conexões em paralelo a um único servidor, onde com o Connection Keep-Alive em jogo, a sobrecarga para a segunda e terceira conexões é drasticamente menor do que para a primeira. É desse efeito que estou falando.

@getify Fantastic, acho que chegamos a algum tipo de consenso. Para refrescar sua memória:

Posso antecipar um contra-argumento sobre o carregamento de seus scripts em partes ...
mas isso é totalmente ortogonal à técnica de carregamento do script, então, por favor, deixe de fora
da discussão.

Sim, concordo que é ótimo carregar seus scripts voláteis em um arquivo JS diferente dos scripts permanentes. Carregar o script que é necessário apenas para uma página específica, apenas naquela página específica, é igualmente ótimo.

Portanto, se eu sou um desenvolvedor web e tenho uma página com vários JavaScripts, o que devo fazer? Usar LABjs ou concatenar meus scripts permanentes em um arquivo e meus scripts voláteis em outro e carregar ambos na parte inferior da tag do corpo com <script defer="true"> ?

Por que devo sujeitar meu aplicativo a dores de cabeça de cache, incompatibilidades de navegador, corrida contra as imagens-na-página e o resto dos problemas que um carregador de script traz?

Se toda a premissa de usar um carregador de script para desempenho é que é mais fácil e simples do que usar duas tags de script ... Tenho uma ponte no Brooklyn para vender para você.

O @getify implementou um servidor web mais de uma vez: o keep-alive não afeta as solicitações simultâneas de forma alguma e apenas reduz os custos das solicitações subsequentes. Um corpo dividido com duas solicitações subsequentes com keep-alive ainda é mais caro do que uma única solicitação. Ter duas solicitações simultâneas para as duas partes do corpo provavelmente terá um desempenho melhor, mas tenha em mente que o navegador só abrirá um número limitado de solicitações simultâneas (dependendo do navegador e configurar algo em torno de 5, eu acho), o que é bom se tudo você faz é carregar seus três arquivos js, mas é, como @jashkenas apontou mais de uma vez, um problema se você tiver outros ativos, como imagens ou arquivos css.

@ jashkenas-

Portanto, se eu sou um desenvolvedor web e tenho uma página com vários JavaScripts, o que devo fazer? Usar LABjs ou concatenar meus scripts permanentes em um arquivo e meus scripts voláteis em outro e carregar ambos na parte inferior da tag body com <script defer = "true">?

TL; DR: ambos

Em primeiro lugar, muitos sites na web são montados por CMSs, o que significa que ter blocos de script embutidos espalhados pela página é comum e MUITO difícil de resolver em termos de manutenção apenas dizendo "mova todo o código para um arquivo". Portanto, acho que a premissa de que _maioria_ sites podem escapar sem ter nenhum "código embutido" para ser executado depois que outro script externo é carregado e executado é improvável, na melhor das hipóteses.

Em segundo lugar, provei que defer age de maneira diferente em relação a DOMContentLoaded em vários navegadores. Em alguns navegadores, os scripts vão antes de estar pronto para DOM; em outros navegadores, vão depois de estar pronto para DOM. Se você tiver um código em seus scripts que depende de acontecer antes ou depois do pronto para o DOM, o uso de defer pode ser um problema. É especialmente verdade que é uma área sensível com muitos mal-entendidos e confusão, então rapidamente se torna "esta não é uma solução simples e direta". É preciso pensar muito mais.

Em terceiro lugar, acho que para muitos sites, alterar sua marcação para usar $LAB.script() vez de &lt;script> é muito mais fácil do que explicar a eles como instalar algum processo Bulid automatizado (ou manual) em seus servidor. Especialmente se esse site estiver em hospedagem compartilhada (a maior parte da web está), e eles não controlam muito seu servidor, pedir-lhes para descobrir os processos de construção para que a manutenção do código não seja perdida é ... bem. .. não trivial.

Essas coisas podem ser superadas? Sim. Claro que podem. Mas eles dão muito trabalho. Em alguns casos (como a coisa pronta para DOM), eles podem precisar de um ajuste meticuloso de seu código. É preciso uma pessoa com esforços dedicados e muita experiência e paixão nesta área para resolver tudo.

Por outro lado, eles podem obter uma "vitória rápida" caindo nos LABjs em vez da tag &lt;script> . Eles têm pouco em que pensar (exceto document.write() ). Na maioria das vezes, "simplesmente funciona". E, na maioria das vezes, eles percebem um aumento imediato na velocidade do carregamento da página. Para a maioria dos sites, é uma grande vitória.

Então, para responder à sua pergunta, eu diria, como disse antes, fazer as duas coisas ... Primeira queda nos LABjs, ver alguns aumentos de velocidade imediatos. Agora, considere fortemente os benefícios de usar um processo de construção para mover você de 15 arquivos para 2 arquivos (1 arquivo dividido pela metade). Quando você fizer isso (se você fizer isso, o que, como eu disse, a maioria não fará), você pode abandonar os LABjs se realmente quiser. Mas não há nenhum dano real (é pequeno e armazena bem, mesmo em dispositivos móveis). Ele continuará a carregar bem seus dois pedaços de arquivo, E fará isso sem as peculiaridades que defer pode causar.

Além disso, ter LABjs já lá torna estupidamente simples para você fazer a etapa 3, que é começar a descobrir qual código você pode "carregar lentamente / sob demanda" mais tarde. Você não pode fazer isso sem um carregador de script. Ter LABjs já lá e familiarizado significa que você não precisa se preocupar em como carregar aquele script on-demand - ele já está planejado.

@ rkh--

Eu tinha demonstrado para mim (especificamente no Apache, alternando a configuração Keep-Alive) como várias solicitações paralelas foram afetadas (positivamente quando Keep-Alive estava lá). Não sou nenhum especialista nesta área, então discutir os detalhes exatos de como isso funciona ou não está além de mim. Posso dizer que o tempo da solicitação 2 foi menor que o tempo da solicitação 1, quando Keep-Alive estava lá. Como o navegador e o servidor fizeram isso, só posso fazer suposições parcialmente informadas em.

Um corpo dividido com duas solicitações subsequentes com keep-alive ainda é mais caro do que uma única solicitação.

Nunca argumentei que o segundo pedido é gratuito. Argumentei que o segundo pedido não é tão caro quanto o primeiro. Portanto, se assumirmos que pelo menos uma solicitação deve ser feita, ter uma segunda solicitação em paralelo NÃO é a mesma coisa que ter duas conexões completamente independentes para o mesmo servidor, em termos de overhead ou custo de tempo.

A título de estimativa, parecia que a Solicitação 1 era X para o serviço e a 2ª em paralelo com Keep-Alive presente era 0,7X. Foi-me explicado que o servidor conseguiu utilizar parte da sobrecarga de conexão existente para atender à segunda solicitação, tornando-o um pouco mais barato. Com o Keep-Alive desativado, a segunda solicitação não teve essa diminuição mensurável.


Toda essa discussão é uma toca de coelho seriamente profunda. Não sou especialista em servidores. Eu não tenho que ser. Eu só posso explicar que eu realmente vi (e criei testes) em torno deste tópico exato ... posso testar aquele único tempo de carregamento de arquivo de 100k vs. carregar duas metades desse mesmo arquivo em paralelo, e o segundo teste será qualquer mensurável quantidade mais rápido. Como eu disse, vi algo entre 15-25% mais rápido com o teste em blocos paralelos. Como ele fez isso e conseguiu superar de alguma forma o terrível efeito "OMG HTTP RESPONSE OVERHEAD IS TERRIBLE" e ainda se beneficiar de dois carregamentos paralelos, acho que não estou qualificado para provar cientificamente. Mas definitivamente o fez por obvservation.

Cristo, vocês digitam rápido. Termino de ler, recarrego a página e há mais nove comentários.

Eu preciso de ajuda. Eu tentei identificar exatamente onde neste tópico passamos de discutir _o que funciona melhor para um arquivo HTML clichê_ para discutir _se os carregadores de script são, em todos os casos, óleo de cobra_.

@getify , você certamente deve defender os LABjs e responder às críticas específicas feitas por outras pessoas no tópico, mas (exceto @jashkenas) acho que aqueles que criticam os LABjs estão fazendo isso para demonstrar que não é a melhor solução para um boilerplate. Você argumenta que é mais fácil converter páginas legadas em LABjs do que script[defer] , e isso pode ser verdade, mas como isso se aplica a um arquivo HTML clichê (que é, por definição, começando do zero)?

Você diz que ele foi projetado para pessoas que não têm processos de construção sofisticados, mas também parece defender a concatenação, a divisão em blocos de tamanhos iguais e o carregamento em paralelo. Não é uma tarefa para um script de construção? Novamente, parece a escolha errada para um clichê projetado para fornecer padrões inteligentes ao usuário. Se um usuário deseja aquele suposto aumento de velocidade de 20-30%, ele pode optar por atualizar mais tarde sobre o que o clichê oferece, mas isso não é uma tarefa trivial.

Dito isso, se vocês quiserem continuar com o tópico geral ("Carregadores de script: ferramenta valiosa ou óleo de cobra?"), Ficarei feliz por aqui e farei pipoca.

@getify : Posso concordar que a 2ª e a 3ª conexões podem ser abertas mais rápido do que a primeira - a primeira espera pelo DNS e, possivelmente, o roteamento do primeiro pacote para o servidor é um pouco mais lento do que rotear o resto pelo mesmo caminho. Em HTTPS SSL, o cache de sessão ajuda muito as conexões subsequentes.

No entanto, não vejo relevância de Keep-Alive nesta situação. _Requests_ subsequentes na mesma conexão são iniciados mais rapidamente com Keep-Alive, mas esses pedidos são seriais dentro da conexão.

Estou quase terminando aqui - acabei de chegar ao meu momento "louco como o inferno e não vou agüentar mais" com respeito aos carregadores de script.

Dito isso, acho que este tópico, para um festival de chamas, tem sido bastante produtivo. Se o LABjs quiser reivindicar os sites infelizes e incompetentes e deixar sozinhas as pessoas que realmente desejam que seus sites carreguem rápido, é um grande passo em frente.

cara, relaxa

@ savetheclocktower--

Perguntas justas.

Eu não comecei minha participação neste tópico defendendo fortemente a inclusão de LABjs (ou qualquer carregador de script) no h5bp. Acho que é útil (veja abaixo), mas não era uma grande preocupação minha estar perdendo o sono. Claramente, este tópico se transformou em um ataque total a tudo o que é "carregamento de script". Isso é, obviamente, algo com que me preocupo um pouco mais.

Você diz que ele foi projetado para pessoas que não têm processos de construção sofisticados, mas também parece defender a concatenação, a divisão em blocos de tamanhos iguais e o carregamento em paralelo. Não é uma tarefa para um script de construção?

Eu defendo primeiro para mover todas as suas dezenas de tags de script para um carregador de script paralelo como LABjs. Isso requer nada mais do que a capacidade de ajustar sua marcação. Essa é uma etapa muito mais fácil / menos intimidante do que dizer a um site familiar para usar um sistema de compilação baseado em node.js automatizado, por exemplo.

E para quem PODE fazer builds de seus arquivos, defendo que o LABjs ainda tem benefícios, pois pode ajudar a carregar esses trechos em paralelo. Se você discordar de que os trechos são de alguma forma úteis, você não verá nenhuma razão para usar LABjs acima de defer . Mas se você pode ver porque chunking _pode ser_ útil, então deve seguir-se que um carregador de script _pode também ajudar_ nesse processo.

Novamente, parece a escolha errada para um clichê projetado para fornecer padrões inteligentes ao usuário.

A única razão pela qual eu acho que um carregador de script (especificamente um que é projetado, como LABjs, para ter um mapeamento um-para-um entre as tags de script e script() chamadas) tem um benefício em um clichê é que em um clichê , você freqüentemente vê uma instância de algo (como uma tag) e sua tendência ao construir sua página é apenas copiar e colar quantas vezes você precisar. Portanto, se você tiver um padrão de baixo desempenho (tag de script) no boilerplate, a tendência das pessoas será duplicar a tag de script uma dúzia de vezes. Eu acho que, em média, se eles duplicassem a chamada $LAB.script() várias vezes, há uma chance decente de que seu desempenho não seja tão ruim quanto teria sido.

Essa é a única razão pela qual comecei a participar deste tópico. É a única razão pela qual eu discordei do comentário sobre "fé cega" de

Entãooooooooooo sim.


Acho que está claro que essa discussão foi além se um carregador de script é apropriado para o projeto h5bp. Mas isso é bom, pois vale a pena explorar este tópico.


independentemente, estou muito interessado em casos de teste reproduzíveis junto com os resultados dos testes.

Parece também que a especificação de @defer foi escrita para proteger alguns dos comportamentos erráticos que os navegadores oferecem junto com ela. Esse comportamento deve ser documentado. Posso ajudar a migrar para o MDC quando estiver pronto.

Precisamos de uma documentação direta sobre esses comportamentos que capture todos os navegadores, diferentes tipos de conexão e efeitos de rede. Não tenho certeza se um equipamento de teste deve usar cuzillion ou assetrace, mas isso pode ser determinado.

Eu criei um tíquete para reunir algum interesse nesse https://github.com/paulirish/lazyweb-requests/issues/42

Junte-se a mim lá se você estiver nas tarefas _superfun_ de pesquisa do webperf e documentação de evidências.

Vamos considerar este tópico encerrado, senhores.

O carregamento lento não é o principal benefício dos módulos AMD, como @import durante o desenvolvimento e executar uma compilação automatizada para combinar folhas de estilo também é recomendado para projetos grandes ...

Acho que este post que escrevi ano passado se encaixa no assunto: O dogma da performance - Não se trata apenas de performance e certifique-se de que você não está _perdendo seu tempo_ "otimizando" algo que não faz nenhuma _real_ diferença ...

E eu estou com @SlexAxton , eu quero AMD, mas tags de script simples provavelmente são suficientes para a maioria das pessoas. Talvez uma abordagem válida seria adicionar uma nova configuração para escolher o projeto AMD e executar o otimizador RequireJS em vez das tarefas _concat_ ( tarefa Ant do otimizador RequireJS ), isso seria muito legal e provavelmente não tão difícil de implementar.

Vamos considerar este tópico encerrado, senhores.

@paulirish E quanto a incluir suporte AMD? Onde devemos discutir isso?

@benatkin abre um novo tíquete mano.

@paulirish OK, obrigado. @jrburke , você poderia abrir um novo tíquete para continuar a discussão que você iniciou? Acho que vou adicionar um comentário, mas não acho que posso apresentar um caso para o suporte da AMD tão bem quanto você.

Divertido e informativo. Obrigado rapazes.

Acho que alguém precisa iniciar um novo projeto de carregador de script e o chamou de "Issue28". :)

Para compatibilidade mais ampla, o desempenho rápido pode ser obtido colocando o script no final, minify, gzip, mas não adie. Pelo menos não até que a compatibilidade do navegador seja consistente por alguns anos consecutivos.

Gargalos podem vir de anúncios, muito javascript, HTML inchado, muito CSS, muitos iframes, muitas solicitações, latência do servidor, javascript ineficiente. Aplicativos que usam muitas bibliotecas de terceiros têm problemas causados ​​não apenas por muito javascript, mas mais do que isso, eles tendem a também ter muitos outros problemas, principalmente HTML inchado, HTML inválido, muito css e javascript ineficiente. O Twitter vem bem à mente, com duas versões do jQuery e dois manipuladores de onscroll que causam uma rolagem na rolagem da coluna certa.

O retrocesso é que, se você souber o que está fazendo, poderá evitar esses problemas. Você não precisa de coisas como jQuery ou sublinhado e, portanto, seus scripts são muito menores. Você escreve HTML e CSS limpos, simples e válidos. Consequentemente, suas páginas carregam mais rápido, o aplicativo é mais flexível em termos de mudança e o SEO melhora. E então, usar um carregador de script apenas adiciona complexidade e sobrecarga desnecessárias.

https://github.com/BroDotJS/AssetRage

ESTRONDO! Eu fecho os clubes e fecho os fios.

Que discussão ... uau.

Imo, a discussão começou no contexto do h5bp, que se destina a ser um ponto de partida para desenvolvedores web.
Como tal, você pode afirmar que o webdev usando o h5bp terá, na verdade, um HTML limpo, um CSS limpo, um bom .htaccess etc. e _talvez_ até _não_ sofra de muitas imagens, JS ineficiente, muitos JS ruins de terceiros etc. Você sabe, porque o desenvolvedor da web que escolhe usar o h5bp de alto desempenho e por isso está preocupado com o desempenho e prestará atenção às coisas não-h5bp que vão para a (s) página (s).

A partir da discussão, e neste contexto, acho que infelizmente não há evidências suficientes para tirar uma conclusão final.
Estou com Paul para iniciar a pesquisa e documentar o que precisa ser documentado.
Conte comigo em Paul.

Nota. Não estou muito familiarizado com a AMD e, à primeira vista, parece intimidante para mim, ou pelo menos não é algo que eu possa aprender com facilidade. Acho que a maioria dos desenvolvedores web 'comuns' concorda.
O material que você vê no h5bp precisa ter uma barreira de entrada baixa, ou não será usado e a captação de h5bp pode ser mais lenta do que seria sem ele.
Duvido que algo como AMD pertença ao h5bp.
Mantenha simples.

E outro comentário ....
'Colocando scripts na parte inferior' e 'Concatenar arquivos JS em um único arquivo' tem estado no topo da lista de Melhores Práticas do Web Perf por muitos anos. Então, por que> 90% da média de sites por aí, construídos por desenvolvedores internos e pelas principais agências de marcas, ainda têm várias tags de script no HEAD? Sério, por que isso?

E os outros 9% têm um único arquivo JS concatenado ... no HEAD.
Raramente vejo um site 'normal' que _não_ é construído por algum desenvolvedor de alto desempenho da web com um script na parte inferior.

Os desenvolvedores continuam construindo sites como fazem há anos.
Os proprietários de sites se preocupam mais com design e recursos, então é nisso que os desenvolvedores gastam seu tempo.

Mudar a forma de trabalhar, o sistema de construção, o código ... tem que ser fácil, muito fácil, senão não vai acontecer.

Eu trabalhei em muitos sites onde combinar o JS no HEAD em um único arquivo e carregá-lo na parte inferior do BODY quebrou as páginas do site. E depois? Na maioria dos casos, não é simplesmente uma hora de trabalho para consertar isso. É preciso haver refatoração séria ... e isso não acontece por falta de conhecimento e, principalmente, de tempo.

(certo, o tópico está fechado ...)

Estamos falando de uma biblioteca construída sobre jQuery e Modernizr. Diz tudo, realmente. Quem usa isso? Que merda, esqueci o Twitter.com, que usa dois jQuerys e também tem no código-fonte o seguinte:

 Linha 352, Coluna 6: Div da tag final vista, mas havia elementos abertos.
 Linha de erro 350, coluna 6: elemento não fechado ul.
 Linha de erro 330, coluna 6: elemento não fechado ul.

E o problema de esperar que o navegador corrija os erros é que o HTML4 não definiu os mecanismos de correção de erros e, portanto, você acabará com um sabe-se lá quem-sabe-onde. Claro, o HTML5 define o tratamento de erros, mas não é retroativo - ainda existem muitos navegadores "antigos" por aí.

E falando merda, alguém aqui deu uma olhada nos shims do jQuery ES5?

BTW, você tem algo a acrescentar à sua afirmação "que o webdev usando o h5bp terá um HTML limpo", aaronpeters?

@Garretts ok, ok, eu deveria ter escrito "provavelmente_ terá HTML limpo"

:-D podemos sempre ter esperança!

Derrotar um cavalo morto, eu sei ... mas ao mesmo tempo que estávamos tendo essa discussão cintilante, a versão atual do LABjs na verdade tinha um bug que fazia com que o JavaScript fosse executado na ordem errada em alguns navegadores: https: //github.com/getify/LABjs/issues/36

Oh A ironia.

deve. resistir. postagem. totalmente. [inapropriado. imagem. para. anterior. declaração .... aggggh! AGONIA!

Minha parte favorita foi quando o cara que fez dhtmlkitchen.com (atualmente totalmente confuso ) começou a falar sobre erros de marcação.

Esse site foi transferido para Paulo Fragomeni. Sim fiz e tenho orgulho do que escrevi lá, como aqui. Faça uma captura de tela do seu avatar fraco, idiota.

... e depois que você terminar com isso, tente puxar sua cabeça para fora da sua bunda e entender a diferença entre meu antigo site pessoal (que não é mais mantido por mim) e um que é desenvolvido por uma equipe e financiado por uma empresa lucrativa e multimilionária (embora o Twitter possa valer bilhões de AFAIK).

Ainda bem que estamos mantendo isso elegante e _ no tópico_, pessoal.

jashkenas obteve as informações relevantes no início desta discussão.

Mas então houve a reação. Não! Não deve ser! Souders disse para fazer isso! E havia o mau conselho de usar o adiamento, sem se importar como ele falha quando falha.

E então, ironicamente, do nada, surgiu uma alegação de que os usuários de h5bp estariam fazendo as coisas corretamente. E isso é muito irônico porque este comentário veio _após_ comentários de seus apoiadores que evidentemente produzem marcação inválida e usam uma carga de camadas de abstração de terceiros (e outras horríveis). E depois do comentário sobre o uso de adiar.

E então o que tudo isso tem a ver com o fato de dhtmlkitchen.com estar fora do ar? Absolutamente nada, obviamente. Isso foi apenas um golpe fraco de um batedor de h5bp que não suporta ouvir críticas.

Bros.
Cara.
Bros.

Este tópico está encerrado. Lembrar? Você não tem que ir para casa, mas você não pode pegar fogo aqui.

Ei, vocês, lembram-se daquela vez em que criamos um tópico épico em que havia vários debates, guerras pessoais, pessoas ficando com raiva por todo lado, uma ou duas imagens obscenas e um bom momento? Não posso acreditar que era grátis. Devíamos fazer isso de novo algum dia.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

alrra picture alrra  ·  18Comentários

gaurav21r picture gaurav21r  ·  21Comentários

coliff picture coliff  ·  14Comentários

coliff picture coliff  ·  12Comentários

davidmurdoch picture davidmurdoch  ·  30Comentários