sentença original: Https://Wangdoc.Com/javascript/index.Html
Navegador Ambiente Overview
JavaScript é uma linguagem de script embutido no navegador. Em outras palavras, o navegador integrado motor de JavaScript, e fornece uma variedade de interfaces, permitindo JavaScript script pode controlar várias funções do browser. Assim que a página da Web incorporado scripts JavaScript, navegador carrega a página, ele irá para executar o script, de modo a atingir o objectivo de operar um navegador, para alcançar uma variedade de desempenho dinâmico de suas páginas.
Este capítulo descreve os vários início de uma interface de JavaScript fornecido pelo navegador. Em primeiro lugar, o método de código JavaScript incorporado em páginas da Web.
O método de código incorporado na página web
código JavaScript incorporado em páginas da Web, existem três métodos principais.
<script>
Elemento incorporado diretamente código.<script>
Tag carregamento script externo- Propriedades de eventos
- protocolo de URL
código de elementos de script embutido
<script>
elementos internos podem diretamente escrever código JavaScript.
<script>
var x = 1 + 5;
console.log(x);
</script>
<script>
Há uma etiqueta type
atributo que especifica o tipo de script. Para o script JavaScript, a type
propriedade pode ser definida como dois tipos de valor.
text/javascript
: Este é o valor padrão, mas também o valor da história sempre foi set. Se você omitir atype
propriedade, este é o valor padrão. Para navegadores mais antigos, defina este valor melhor.application/javascript
: Para os navegadores mais recentes, definido como o valor recomendado.
<script type="application/javascript">
console.log('Hello World');
</script>
Uma vez que o <script>
rótulo é o código JavaScript padrão. Portanto, quando o script JavaScript incorporado type
atributo pode ser omitido.
Se o type
valor da propriedade, o navegador não reconhece, não vai executar o código dentro. Aproveite esta, você pode <script>
inserir qualquer texto no rótulo, basta adicionar um navegador não reconhece o type
atributo.
<script id="mydata" type="x-custom-data">
console.log('Hello World');
</script>
O código acima, o navegador não irá executar, não vai exibir seu conteúdo, porque eles não entendem suas type
propriedades. No entanto, o <script>
nó ainda existe no DOM, você pode usar <script>
o nó de text
atributo ler seu conteúdo.
document.getElementById('mydata').text
// console.log('Hello World');
roteiro elemento de carga script externo
<script>
As tags também pode carregar o arquivo de script externo especificado.
<script src="https://www.example.com/script.js"></script>
Se o arquivo de script usando caracteres não-inglês, você deve também indicar a codificação de caracteres.
<script charset="utf-8" src="https://www.example.com/script.js"></script>
Script carregado deve ser um código JavaScript puro, não pode ter HTML
o código e <script>
etiquetas.
Carregando scripts externos e blocos de código adicionado diretamente, ambos os métodos não podem ser misturados. O código a seguir console.log
declarações diretamente ignorado.
<script charset="utf-8" src="example.js">
console.log('Hello World!');
</script>
Para impedir que os atacantes adulteração de script externo script
tag permite que você defina a integrity
propriedade, escreva para a assinatura roteiro Hash externo é utilizado para verificar a consistência do script.
<script src="/assets/application.js"
integrity="sha256-TvVUHzSfftWg1rcfL6TIJ0XKEGrgLyEq6lEpcmrG9qs=">
</script>
O código acima, script
o rótulo tem um integrity
atributo que especifica o script externo /assets/application.js
assinatura SHA256. Uma vez que o script foi alterado, resultando assinaturas SHA256 não correspondem, o navegador irá recusar-se a carga.
Propriedades de eventos
propriedades de evento (como elementos da página onclick
e onmouseover
), você pode escrever código JavaScript. Quando ocorre o evento especificado, ele irá chamar o código.
<button id="myBtn" onclick="console.log(this.id)">点击</button>
O código de propriedade de evento acima, apenas uma instrução. Se houver várias declarações, separados por ponto e vírgula pode ser.
protocolo de URL
apoio URL javascript:
acordo que o código é escrito na posição do URL, ao usar este URL irá executar código JavaScript.
<a href="javascript:console.log('Hello')">点击</a>
A barra de endereços do navegador também pode executar javascript:
o protocolo. Será javascript:console.log('Hello')
colocado na barra de endereços, pressione a tecla Enter irá executar o código.
Se o código JavaScript retorna uma string, o navegador irá criar um novo documento, exibir o conteúdo da corda, o conteúdo original do documento desaparecerá.
<a href="javascript: new Date().toLocaleTimeString();">点击</a>
O código acima, após o usuário clicar sobre o link irá abrir um novo documento, que tem a hora atual.
Se o retorno não é uma corda, em seguida, o navegador não irá criar um novo documento, ele não vai saltar.
<a href="javascript: console.log(new Date().toLocaleTimeString())">点击</a>
O código acima, o usuário clica no link, a página não vai saltar, ele só irá mostrar a hora atual no console.
javascript:
Um uso comum do protocolo é para marcar roteiro Bookmarklet. Por causa de marcadores salvos navegador é um URL, por isso javascript:
quando o URL também podem ser salvos no interior, o usuário seleciona este indicador irá executar o script na página atual. Para evitar bookmarks substituir o documento atual, você pode adicionar um script antes void
, ou, finalmente, adicionar o script void 0
.
<a href="javascript: void new Date().toLocaleTimeString();">点击</a>
<a href="javascript: new Date().toLocaleTimeString();void 0;">点击</a>
Tanto o texto acima, clique no link, o código não será executado uma página de salto.
elementos de script
trabalho
Habilitar o JavaScript do navegador, principalmente através dos <script>
elementos para completar. processo de carregamento da página normal é assim.
- web browser HTML, enquanto o download, enquanto início de análise. Em outras palavras, não espere até que o download terminar, eles começam a determinação.
- processo de resolução, o navegador vê
<script>
elementos na deliberação de suspensão, o controle da página renderização encaminhado para o motor de JavaScript. - Se as
<script>
referências do elemento scripts externos, baixar o script e, em seguida, executar, ou para executar código diretamente. - motor de JavaScript estiver concluído, o controle é retornado para o motor de renderização, currículo análise de HTML páginas para baixo.
Ao carregar script externo, a página do browser tornando pausas, à espera de que o script de download e execução é concluída, e depois continuar a prestar. A razão é que o código JavaScript pode modificar o DOM, é necessário dar-lhe o direito de controle, caso contrário ele irá levar a concurso problemas fio complicado.
Se o tempo de carregamento de script externo é muito longo (não têm sido capazes de completar o download), o navegador terá que esperar o download é script completo, resultando em perda prolongada da página de resposta, o navegador irá mostrar "animação suspensa" do Estado, que é chamado de "bloqueio efeito" .
Para evitar isso, é uma boa prática de <script>
etiqueta são colocados na parte inferior da página, em vez da cabeça. Assim, mesmo no script não responde rosto, a renderização de páginas web principal tenha sido concluída, o usuário pode ver pelo menos conteúdo, em vez de rosto uma página em branco. Se algum código de script é muito importante, deve ser colocada no cabeçalho da página, o melhor código é escrito diretamente para a página em vez de conectar um arquivo de script externo, que pode encurtar o tempo de carregamento.
Os arquivos de script são colocados na cauda da página para carga, há um benefício. Porque antes de chamar DOM DOM geração estrutura de nó, JavaScript vai reclamar se o script na página para carregar a cauda, não há problema, porque quando o DOM certamente foi gerado.
<head>
<script>
console.log(document.body.innerHTML);
</script>
</head>
<body>
</body>
Quando o código acima irá executar erro, porque o document.body
elemento não foi gerado.
Uma solução é definir DOMContentLoaded
uma função de evento de retorno de chamada.
<head>
<script>
document.addEventListener(
'DOMContentLoaded',
function (event) {
console.log(document.body.innerHTML);
}
);
</script>
</head>
O código acima, designado DOMContentLoaded
após o incidente, começou a executar o código. DOMContentLoaded
O evento só será acionado após a geração estrutura DOM.
Outra solução é usar <script>
o rótulo onload
atributo. Quando o <script>
rótulo especificado download de arquivos script externo e análise estiver concluída, irá disparar um load
evento, você pode colocar o código que você precisa para realizar, no caso de um interior função de retorno.
<script src="jquery.min.js" onload="console.log(document.body.innerHTML)">
</script>
No entanto, se o script na parte inferior da página, você pode maneira completamente normal para escrever o acima de dois métodos não são necessários.
<body>
<!-- 其他代码 -->
<script>
console.log(document.body.innerHTML);
</script>
</body>
Se houver várias script
marcas, como segue.
<script src="a.js"></script>
<script src="b.js"></script>
O navegador irá baixar em paralelo a.js
e b.js
, no entanto, irá garantir a implementação da primeira execução a.js
, e depois executado b.js
, mesmo que este último antes que o download estiver concluído, também. Em outras palavras, a ordem de execução de script é determinada pela ordem em que aparecem na página, que é a de garantir que as dependências entre os scripts não ser prejudicada. Naturalmente, estes dois scripts terá de carga "efeito de bloqueio" deve esperar até que eles são carregados, o navegador continuará processar a página.
Analisar e executar CSS, vai produzir obstrução. navegador Firefox irá esperar até que o script anterior todas as folhas de estilo são baixados e analisados terminar, e depois executar o script; Webkit é as referências de script do estilo uma vez encontrado, ele irá suspender o script, faça o download e analisar a folha de estilo até a conclusão, em seguida, recomeça.
Além disso, recursos do mesmo nome de domínio, tais como arquivos de script, arquivos de folhas de estilo, arquivos de imagem e outros navegadores geralmente limitado, e download até 6 a 20 recursos, que é até as conexões TCP abertas mesmo tempo é limitado, o que é evitar muito estresse no servidor. Se o recurso é de um nome de domínio diferente, você não tem essa limitação. Então, geralmente sob arquivos estáticos em um domínio diferente, a fim de acelerar a velocidade de download.
propriedade Adiar
A fim de resolver os problemas de bloqueio de renderização página de download arquivo de script, um método é <script>
adicionar elementos defer
de propriedade. Seu papel é o de atrasar a execução do script, que esperar até que o DOM é gerado, e depois executar o script.
<script src="a.js" defer></script>
<script src="b.js" defer></script>
O código acima, apenas para esperar até depois do DOM está pronto, vai ser realizada a.js
e b.js
.
defer
Executando propriedades do processo do seguinte modo.
- Navegador começar a analisar uma página HTML.
- processo de análise, verificou-se com os
defer
atributos<script>
do elemento. - Continue para baixo as páginas parses browser HTML durante o download de um paralelo
<script>
elementos de script externo carregado. - O navegador foi concluída a análise de uma página HTML, e então voltar e executar o script tem download acabado.
Com defer
propriedade, o navegador para baixar um arquivo de script, não bloqueie a renderização da página. Baixe o arquivo de script DOMContentLoaded
antes de executar desencadeada por eventos (ie acabado de ler o </html>
rótulo), e pode garantir a ordem de execução da ordem em que aparecem na página.
Para construída em vez de carregar um script externo script
etiquetas, e gerado dinamicamente script
rótulo defer
propriedade não funciona. Além disso, o uso de defer
um monte de script externos não deve usar o document.write
método.
atributo async
Outra maneira de resolver o "efeito de bloqueio" é <script>
um elemento adicional async
atributos.
<script src="a.js" async></script>
<script src="b.js" async></script>
async
O atributo papel é usado por outro processo para baixar o script, não bloqueie tornando download.
- Navegador começar a analisar uma página HTML.
- processo de análise encontrou com
async
atributosscript
tags. - Continue para baixo as páginas parses browser HTML durante o download de um paralelo
<script>
tag script externo. - Download Script for concluída, a pausa navegador páginas analisar HTML, iniciar os scripts de download.
- O script for concluído, o currículo navegador analisar páginas HTML.
async
As propriedades podem ser baixados ao mesmo tempo para garantir o script, o navegador continua a desempenhar. Note-se que uma vez que o uso desta propriedade, não podemos garantir a ordem de execução do script. Que script para baixar o final, é a primeira implementação desse script. Além disso, async
as propriedades do arquivo de script dentro do código, não deve usar document.write
o método.
defer
Propriedade e async
propriedade no final qual usar?
De um modo geral, se há dependências entre os scripts, o uso async
da propriedade, se houver dependências entre scripts, utilize a defer
propriedade. Se você usar async
e defer
propriedade, este último não funcionar, o comportamento do navegador pelo async
atributo decisão.
roteiro carregado dinamicamente
<script>
Os elementos podem também ser gerada dinamicamente, gera e, em seguida, inserir uma página, de modo a atingir roteiro de carga dinâmica.
['a.js', 'b.js'].forEach(function(src) {
var script = document.createElement('script');
script.src = src;
document.head.appendChild(script);
});
A vantagem dessa abordagem é que gerado dinamicamente script
rótulo não bloquear renderização de páginas, não fará com que a animação navegador suspenso. Mas o problema é que esse método não garante a ordem de execução do script, que arquivo de script antes que o download estiver concluído, ele é executado em primeiro lugar.
Se você quiser evitar esse problema, você pode definir a propriedade assíncrona false
.
['a.js', 'b.js'].forEach(function(src) {
var script = document.createElement('script');
script.src = src;
script.async = false;
document.head.appendChild(script);
});
O código acima não bloqueia a renderização da página, mas também para garantir que b.js
na a.js
implementação das costas. Mas note que este código é carregado na parte de trás do arquivo de script, então eles têm que esperar para b.js
a execução para completo antes da execução.
Se você deseja especificar uma função de retorno de chamada para o script carregado dinamicamente, você pode usar a seguinte redação.
function loadScript(src, done) {
var js = document.createElement('script');
js.src = src;
js.onload = function() {
done();
};
js.onerror = function() {
done(new Error('Failed to load script ' + src));
};
document.head.appendChild(js);
}
protocolo de carga utilizada
Se você não especificar o protocolo, padrão de download do navegador usando o protocolo HTTP.
<script src="example.js"></script>
O acima example.js
padrão é usar o protocolo HTTP para download, se você deseja fazer o download usando o protocolo HTTPS, você deve especificar o.
<script src="https://example.js"></script>
Mas às vezes nós vai querer determinar o acordo protocolo de carregamento com base na própria página, em seguida, a seguinte redação pode ser usado.
<script src="//example.js"></script>
A composição do navegador
O navegador do núcleo é duas partes: o motor de renderização e intérprete JavaScript (também conhecido como motor de JavaScript).
motor de renderização
O principal efeito do mecanismo de renderização que o código da página web é processada como documentos planos o usuário pode visualmente perceptível.
Navegadores diferentes têm diferentes motor de renderização.
- engine Gecko: Firefox
- Safari: WebKit 引擎
- motor Blink: Chrome
- engine Trident: IE
- Borda: edgehtml 引擎
processo motor de renderização da página web, normalmente dividido em quatro etapas.
- Analisando código: resolve código HTML para DOM, análise de código CSS é CSSOM (Object Model CSS).
- Objeto Síntese: DOM e síntese CSSOM prestação de uma árvore (render árvore).
- Layout: tornar árvore disposição calculada (layout).
- Draw: A árvore tornar desenhados na tela.
Mais de quatro passos não são estritamente execução sequencial, muitas vezes o primeiro passo ainda não está completa, segundo e terceiro passo já começou. Então, vamos ver esta situação: o código HTML da página não é baixado, mas o navegador tem mostrado o conteúdo.
fluxo pesado e redesenho
Tornar árvore em um layout de página, conhecido como o "fluxo de layout" (fluxo), o layout da página é exibido neste processo, conhecido como a "desenhar" (pintura). Eles têm um efeito de bloqueio, e vai gastar um monte de tempo e recursos computacionais.
Depois de geração da página, operação scripts e folhas de estilo operação irá desencadear um "fluxo pesado" (refluxo) e "redesenhar" (repintura). A interação do usuário irá acionar o fluxo pesado e redesenhado, tais como a criação de mouseover ( a:hover
) efeitos, a rolagem da página, entrar na caixa de entrada de texto, alterar o tamanho da janela, e assim por diante.
E redesenhar o fluxo pesado não necessariamente ocorrem em conjunto, levará inevitavelmente ao redesenho fluxo pesado, você não precisa necessariamente redesenhar o fluxo pesado. Como alterar os elementos de cor, ela só vai levar ao redesenhar sem causar fluxo pesado; mudar os elementos de layout, e vai levar para redesenhar o fluxo pesado.
Na maioria dos casos, o navegador determina a inteligência, eo fluxo pesado redesenho limita apenas à sub relevante acima, minimizando preço de custo, sem página mundial regenerado.
Como um desenvolvedor, você deve tentar reduzir o número eo custo de tentar redesenhar. Por exemplo, não tente alterar o topo elementos DOM, e a mudanças nos elementos DOM subjacentes no lugar, outro exemplo, redesenhar table
o layout e flex
layout, o custo será relativamente grande.
var foo = document.getElementById('foobar');
foo.style.color = 'blue';
foo.style.marginTop = '30px';
O código acima só vai levar a um redesenho porque as mudanças DOM navegador se acumulam, então a execução de uma vez.
Aqui estão algumas técnicas de otimização.
- DOM DOM para ler ou escrever, tentar escrever juntos, não se misturam. Não ler um nó DOM, em seguida, escrever de imediato, seguido pela leitura de um nó DOM.
- informações de cache DOM.
- Não um por um para mudar o estilo, mas o uso de estilo de classe mudança CSS one-time.
- Uso
documentFragment
manipular DOM - Animação usando o
absolute
posicionamento oufixed
localização, de modo que o impacto sobre outros elementos podem ser reduzidas. - Mostrar elemento escondido somente quando necessário.
- Use
window.requestAnimationFrame()
, porque pode adiar a execução de código quando a re-fluxo para o outro, em vez de fluxo de página pesado imediatamente necessário. - Usando DOM Virtual (DOM virtual) biblioteca.
O que se segue é um window.requestAnimationFrame()
exemplo do efeito de contraste.
// 重绘代价高
function doubleHeight(element) {
var currentHeight = element.clientHeight;
element.style.height = (currentHeight * 2) + 'px';
}
all_my_elements.forEach(doubleHeight);
// 重绘代价低
function doubleHeight(element) {
var currentHeight = element.clientHeight;
window.requestAnimationFrame(function () {
element.style.height = (currentHeight * 2) + 'px';
});
}
all_my_elements.forEach(doubleHeight);
O acima primeiro código, leia cada vez que o DOM, está escrito o novo valor fará com que o rearranjo e interromper o fluxo pesado. O segundo parágrafo do código para todas as gravações são acumulados em conjunto para alterar o código no custo do DOM é minimizado.
motor de JavaScript
O principal papel do motor de JavaScript que lê páginas da web de código JavaScript para ser executado após o seu tratamento.
JavaScript é uma linguagem interpretada, o que significa que não precisa de compilação, dirigida por um intérprete em tempo real. A vantagem é que a operação e as modificações são mais convenientes, você pode atualizar a reinterpretação página; inconveniente é que cada execução deve chamar o intérprete, maior sobrecarga, correr mais lento do que uma linguagem compilada.
A fim de melhorar a velocidade, navegadores atuais, em certa medida compilador gera JavaScript código de bytes semelhante (código de bytes A) do código intermediário para melhorar a velocidade de funcionamento.
Logo no início, o processo de navegador interno JavaScript é a seguinte:
- Leia o código, uma análise lexical (análise léxica), o código de elementos na palavra (token).
- Análise da palavra yuan (análise), o código é organizado em "árvore de sintaxe" (árvore de sintaxe).
- Use "tradutor" (tradutor), código em código byte (bytecode).
- Use "intérprete código de bytes" (intérprete código de bytes), o código de bites na máquina de código.
interpretação progressiva do código de bytes para o código de máquina, é muito ineficiente. A fim de melhorar a velocidade, navegador moderno para um "compilador tempo" (compilador Just In Time, a abreviatura JIT), ou seja, apenas a bytecode do compilador em tempo de execução, usando uma linha onde a linha na qual o compilador, o compilador e cache de resultados ( cache de linha). Normalmente, o programa compilador é o resultado de uma usado frequentemente, apenas uma pequena parte do código, com o cache, corre todo o programa vai ser significativamente melhorada.
código de byte não pode ser executado diretamente, mas é executado em uma VM (Virtual Machine), geralmente conhecido como máquina virtual motor de JavaScript. Nem todos têm máquina JavaScript virtual está em execução bytecode, e alguns máquina virtual JavaScript baseado no código fonte, que é o maior tempo possível, por JIT (just in time) compilador para o código-fonte de compilação diretamente em código de máquina para correr, bytecode omitido etapa. Este não é o mesmo com outras línguas que usam uma máquina virtual (como Java) são. O objetivo é otimizar o código, tanto quanto possível, para melhorar o desempenho. A seguir estão algumas da máquina virtual mais comum JavaScript:
- Chakra (Microsoft Internet Explorer)
- Nitro / JavaScript núcleo (Safari)
- Como (Opera)
- SpiderMonkey (Firefox)
- V8 (Chrome, Chromium)
links de referência
- John Dalziel, A corrida para a parte de velocidade 2: Como JavaScript compiladores trabalho
- Jake Archibald, mergulho profundo nas águas turvas de carga roteiro
- Mozilla Developer Network, window.setTimeout
- Remy Afiado, chamadas de função de Limitação
- Ayman Farhat, Uma alternativa para o mal de JavaScript setInterval
- Ilya Grigorik, Script-injetados "scripts assíncronos" considerados nocivos
- Axel Rauschmayer, ECMAScript 6 promessas (1/2): fundações
- Daniel IMMS, assíncrona vs atributos Adiar
- Craig Buckler, carga não bloqueando JavaScript com HTML5 Async e Adiar
- Domenico De Felice, como os navegadores de trabalho