Prefácio
Acredito que todo mundo encontrou muitos problemas em relação ao carregamento de scripts JavaScript. Principalmente em vários pontos -
1> Problemas com carregamento de arquivos, dependência de arquivo e ordem de execução causada por scripts síncronos e scripts assíncronos
2> Problemas de otimização de desempenho causados por scripts síncronos e scripts assíncronos
Uma compreensão profunda de todos os aspectos do carregamento de scripts não é apenas propícia à solução de problemas práticos, mas também propícia a agarrar e executar a otimização de desempenho.
Primeiro, olhe para qualquer código de tag de script -
A cópia do código é a seguinte:
<script src = "js/myapp.js"> </sCript>
Se colocado em <head>, ele bloqueará todo o trabalho de renderização da página, fazendo com que o usuário permaneça em um estado "Tela Branca da Morte" até que o script seja carregado e executado. O script no final do <body> só permitirá que o usuário veja a página estática sem vitalidade. Onde a renderização do cliente deve estar espalhada com controles ineficazes e caixas vazias. Faça um caso de teste -
A cópia do código é a seguinte:
<! Doctype html>
<html>
<head lang = "en">
<meta charset = "utf-8">
<Title> Script de carregamento assíncrono </ititle>
<script src = "js/test.js"> </script>
</head>
<Body>
<div> Estou contente </div>
<img src = "img/test.jpg">
</body>
</html>
Entre eles, o conteúdo em test.js -
A cópia do código é a seguinte:
Alert ('Eu sou o código de script na cabeça. Depois de executar o JS aqui, a renderização do conteúdo do corpo começa!');
Veremos que o alerta é um ponto de pausa e, neste momento, a página está em branco. No entanto, esteja ciente de que a página inteira foi carregada neste momento. Se o corpo contiver tags para certos atributos SRC (como a tag IMG acima), o navegador começou a carregar o conteúdo relevante no momento. Em suma, deve -se notar que o tempo de trabalho do mecanismo JS e do mecanismo de renderização são mutuamente exclusivos (alguns livros chamam de tópico da interface do usuário).
Portanto, precisamos que os scripts responsáveis por fazer a página pareçam melhor e o uso melhor devem ser carregados imediatamente, e os scripts que podem ser carregados posteriormente serão carregados posteriormente.
1. Atraso de execução do script
Agora está se tornando cada vez mais popular colocar scripts no final da página <body>. Dessa forma, por um lado, o usuário pode ver a página mais rapidamente e, por outro lado, o script pode operar diretamente os elementos DOM que foram carregados. Essa "mudança" é uma grande melhoria para a maioria dos scripts. O modelo de página é o seguinte -
A cópia do código é a seguinte:
<! Doctype html>
<html>
<head lang = "en">
<!-Metadados e folhas de scripts vêm aqui->
<script src = "headscript.js"> </script>
</head>
<Body>
<!-O conteúdo vai aqui->
<script src = "bodyscript.js"> </sCript>
</body>
</html>
Isso acelera bastante o tempo de renderização da página, mas esteja ciente de que isso pode dar aos usuários a oportunidade de interagir com a página antes que o BodyScript seja carregado. A razão pela qual o navegador não pode carregar os scripts antes de carregar o documento completo é um grande gargalo para documentos grandes transmitidos por conexões lentas.
Idealmente, o carregamento do script deve ser feito simultaneamente com o carregamento do documento e não afeta a renderização do DOM. Dessa forma, uma vez que o documento estiver pronto, o script pode ser executado porque o script correspondente foi carregado na ordem da tag <Script>.
Podemos atender a esse requisito usando o adiamento, isto é,
A cópia do código é a seguinte:
<script src = "adteredScript.js"> </sCript>
Adicionar o atributo de adiamento é equivalente a dizer ao navegador: comece a carregar esse script imediatamente, mas aguarde até que o documento esteja pronto e todos os scripts com o atributo de adiamento terminassem de executar antes de executá -lo.
Dessa forma, colocar scripts de atraso na etiqueta da cabeça trará todos os benefícios de colocar scripts na etiqueta corporal e pode melhorar bastante a velocidade de carregamento de documentos grandes. O modo de página neste momento é -
A cópia do código é a seguinte:
<! Doctype html>
<html>
<head lang = "en">
<!-Metadados e folhas de scripts vêm aqui->
<script src = "headscript.js"> </script>
<script src = "adteredScript.js" adiar> </sCript>
</head>
<Body>
<!-O conteúdo vai aqui->
</body>
</html>
No entanto, nem todos os navegadores suportam o adiamento (para alguns navegadores modernos, se o adiamento for declarado, seus scripts internos não executarão operações de documentação e renderização do Document e DOM. Ambos os atributos de adiamento do IE4+ suportam). Isso significa que, se você deseja garantir que seu script de atraso possa ser executado após o carregamento do documento, você deve encapsular o código de todos os scripts de atraso em uma estrutura como o $ (documento) do jQuery. Vale a pena, porque quase 97% dos visitantes podem desfrutar dos benefícios do carregamento paralelo, enquanto outros 3% dos visitantes ainda podem usar JavaScript completo.
2. Paralelização completa dos scripts
Que os scripts sejam carregados e executados um passo mais rápido. Não quero esperar até que os scripts de adiamento executem um após o outro (adiar nos lembra um cenário de fila ordenado em que o documento está esperando silenciosamente o carregamento do documento) e não quero esperar até que o documento esteja pronto antes de executar esses scripts. Quero carregar e executar esses scripts o mais rápido possível. Aqui pensamos no atributo assíncrono do HTML5, mas esteja ciente de que é uma anarquia caótica.
Por exemplo, carregamos dois scripts de terceiros completamente irrelevantes, e a página funciona bem sem eles, e não se importa com quem corre primeiro e que corre mais tarde. Portanto, o uso do atributo assíncrono nesses scripts de terceiros é equivalente a melhorar sua velocidade de corrida sem gastar um centavo.
O atributo assíncrono é recentemente adicionado ao HTML5. A função é semelhante a adiar, ou seja, permite que a renderização do DOM durante o download de scripts. No entanto, ele será executado o mais rápido possível após o download (ou seja, o mecanismo JS está ocioso e executado imediatamente) e não há garantia de que o script seja executado em ordem. Eles serão concluídos antes do evento Onload.
Firefox 3.6, Opera 10.5, ou seja, 9 e os mais recentes Chrome e Safari suportam o atributo assíncrono. Async e adiar podem ser usados ao mesmo tempo, para que todos os IEs após o IE 4 suportem o carregamento assíncrono, mas tenha cuidado para que o Async substitua o adiar.
Então o modelo de página neste momento é o seguinte -
A cópia do código é a seguinte:
<! Doctype html>
<html>
<head lang = "en">
<!-Metadados e folhas de scripts vêm aqui->
<script src = "headscript.js"> </script>
<script src = "adteredScript.js" adiar> </sCript>
</head>
<Body>
<!-O conteúdo vai aqui->
<script src = "asyncscript1.js" assíncrono adiar> </sCript>
<script src = "asyncscript2.js" assíncrono adiar> </sCript>
</body>
</html>
Preste atenção à ordem de execução aqui - cada arquivo de script é carregado, então o HeadScript.js é executado e, em seguida, o DefferedScript.js é carregado em segundo plano enquanto a renderização do DOM. Em seguida, o DefferedScript.js e os dois scripts assíncronos serão executados no final da renderização do DOM. Observe que, para os navegadores que suportam o atributo assíncrono, esses dois scripts ficarão sem ordem.
3. Carregamento de script programável
Embora as funções das duas propriedades de script acima sejam muito atraentes, elas não são amplamente utilizadas devido a problemas de compatibilidade. Portanto, usamos scripts para carregar outros scripts mais. Por exemplo, queremos carregar apenas um script para usuários que atendem a determinadas condições, que é o "carregamento preguiçoso" frequentemente mencionado.
No nível da API do navegador, existem duas maneiras razoáveis de rastejar e executar scripts de servidor -
1> gerar solicitação de Ajax e usar a função de avaliação para processar a resposta
2> Insira a tag <cript> no DOM
O último método é melhor porque o navegador se preocupará em gerar solicitações HTTP para nós. Além disso, a EVAL também tem alguns problemas práticos: vazamento de escopo, depuração é confuso e também pode reduzir o desempenho. Portanto, se você deseja carregar um script chamado Feature.js, devemos usar um código como o seguinte:
A cópia do código é a seguinte:
var head = document.getElementsByTagName ('Head') [0];
var script = document.createElement ('script');
script.src = 'feste.js';
head.appendChild (script);
Obviamente, precisamos lidar com a escuta de retorno de chamada, e a especificação HTML5 define uma propriedade Onload que pode vincular retornos de chamada.
A cópia do código é a seguinte:
script.onload = function () {
console.log ('Script carregado ...');
}
No entanto, o IE8 e as versões mais antigas não suportam o OnLoad, elas suportam o OnreadyStateChange. Além disso, ainda existem muitas coisas estranhas para lidar com erros. Aqui, você pode se referir a algumas bibliotecas populares de carregamento escolares, como labjs, yepnope, requerjs, etc.
Da seguinte
A cópia do código é a seguinte:
var loadjs = function (url, retorno de chamada) {
var head = document.getElementsByTagName ('Head') [0];
var script = document.createElement ('script');
script.src = url;
script.type = "text/javascript";
head.appendChild (script);
// tag de script, existe um evento ONREADESTATECHANGE sob o IE, e há um evento Onload no padrão W3C
// IE9+ também suporta o Onload of W3C Standard
var ua = navegator.useragent,
ua_version;
// IE6/7/8
if (/msie ([^;]+)/. test (ua)) {
ua_version = parsefloat (regexp ["$ 1"], 10);
if (ua_version <= 8) {
script.onReadyStateChange = function () {
if (this.readyState == "carregado") {
ligar de volta();
}
}
} outro {
script.onload = function () {
ligar de volta();
};
}
} outro {
script.onload = function () {
ligar de volta();
};
}
};
Não vou falar sobre o carregamento assíncrono de scripts no document.write. Agora, poucas pessoas fazem isso porque as diferenças do navegador são realmente esmagadoras.
Observe que, usando o objeto de imagem para pré -carregar os arquivos JS de forma assíncrona, o código JS interno não será executado.
Por fim, vamos falar sobre o script de carregamento assíncrono no requirejs.
O requestJS não garante que os scripts de destino sejam executados sequencialmente, mas garante que sua ordem de execução possa atender aos seus respectivos requisitos de dependência. Portanto, garantimos que todos os scripts sejam carregados em paralelo o mais rápido possível e os executamos de maneira ordenada de acordo com a topologia de dependência.
4. Resumo
OK, quando se trata disso, a declaração do script de carregamento assíncrono acabou. Deixe -me falar sobre a ordem de otimização aqui novamente -
1> Da maneira tradicional, usamos tags de script para incorporá -las diretamente aos documentos HTML. Aqui estão duas situações -
A> Incorporar na etiqueta da cabeça - tenha cuidado para que isso não afete o carregamento paralelo de outros arquivos de recursos estáticos no conteúdo do documento. Afeta a renderização do conteúdo do documento, ou seja, a renderização do DOM neste momento será bloqueada e a tela branca será apresentada.
B> Incorporar na parte inferior da etiqueta corporal - para evitar o fenômeno da tela branca, priorizamos a renderização do DOM e, em seguida, executamos o script, mas o problema ocorre novamente. Vamos falar sobre a primeira pergunta primeiro - se o conteúdo do documento DOM for relativamente grande, a ligação do evento de interação será adiada e a experiência será um pouco pior. Obviamente, precisamos fazer scripts importantes executados primeiro com base nas necessidades. Vamos falar sobre o segundo problema - porque os arquivos de script estão na parte inferior do corpo, o carregamento desses scripts é atrasado em comparação com os scripts na cabeça. Portanto, como no fundo do corpo, não é o ponto final da otimização.
C> Adicionar atributo de adiamento - Esperamos que o script seja carregado em paralelo o mais rápido possível, e ainda colocaremos esse lote de scripts na cabeça. O carregamento do script deve ser feito simultaneamente com o carregamento do documento e não afeta a renderização do DOM. Dessa forma, o script pode ser executado assim que o documento estiver pronto. Portanto, há um atributo de adiamento. Mas preste atenção à sua compatibilidade. Para os navegadores que não suportam o atributo de adiamento, precisamos encapsular o código em um $ (documento) .ready como jQuery. Deve -se notar que todos os scripts com atributos de adiamento são executados em sequência de acordo com sua ordem de aparência, para que eles também sejam estritamente sincronizados.
2> O ponto anterior é sobre scripts de execução síncronos (observe que o processo de carregamento desses scripts é paralelo, mas a diferença entre quem aciona a solicitação primeiro e quem aciona a solicitação). O próximo ponto de otimização é "scripts de execução paralelos". Obviamente, sabemos que, em um momento, apenas um arquivo JS é executado. O "paralelo" aqui significa que quem carrega primeiro, desde que o mecanismo JS esteja ocioso neste momento, ele será executado imediatamente. A otimização aqui é dividida em dois tipos -
a> Adicionando a propriedade Async - ela pode realmente concluir o ponto de otimização que mencionamos acima, mas possui altas limitações, ou seja, é apenas para carregamento de scripts sem dependência. O exemplo mais apropriado é introduzir vários scripts de terceiros. Além disso, a combinação com o atributo Deffer é realmente um grande negócio. Obviamente, também tem problemas de compatibilidade. Os três problemas acima levaram à sua aplicação pouco frequente. Ao usar o Async, você deve prestar muita atenção aos problemas de dependência.
B> Scripts Carregando scripts - Obviamente, usamos isso para alcançar o objetivo da "execução paralela dos scripts". Ao mesmo tempo, também facilitamos o controle das dependências de scripts, por isso usamos o gerenciamento de carga inteligente para carga assíncrona nos requisitos.
OK, isso é tudo.
Aqui, estou apenas falando sobre o conteúdo relacionado a scripts de carregamento assíncrono. Há outra parte do conteúdo, que é o carregamento assíncrono de arquivos de estilo ou outros recursos estáticos. continua......