Análise detalhada de um navegador da Web moderno (parte 2)

Mariko Kosaka

O que acontece na navegação

Esta é a segunda parte de uma série em quatro postagens do blog sobre o funcionamento interno do Chrome. Na postagem anterior, vimos como diferentes e threads lidam com diferentes partes de um navegador. Nesta postagem, vamos nos aprofundar em como cada processo e thread se comunicam para exibir um site.

Vejamos um caso de uso simples de navegação na Web: você digita um URL em um navegador e depois ele busca dados da Internet e exibe uma página. Nesta postagem, vamos nos concentrar na parte em que o usuário solicita um site, e o navegador se prepara para renderizar uma página. Isso também é conhecido como navegação.

Tudo começa com um processo de navegação

Processos do navegador
Figura 1: interface do navegador na parte de cima, diagrama do processo do navegador com interface, rede e armazenamento linha na parte de baixo

Como abordamos parte 1: CPU, GPU, memória e arquitetura de vários processos, tudo o que está fora de uma guia é tratado pelo processo do navegador. O processo do navegador tem sequências como a sequência da interface que desenha botões e campos de entrada do a linha de execução de rede, que lida com a pilha de rede para receber dados da Internet, a linha de execução de armazenamento que controla o acesso aos arquivos e muito mais. Quando você digita um URL no endereço sua entrada será tratada pelo thread de UI do processo do navegador.

Navegação simples

Etapa 1: gerenciar as entradas

Quando um usuário começa a digitar na barra de endereço, a primeira coisa que a linha de execução de interface pergunta é: “Is this a consulta de pesquisa ou URL?". No Chrome, a barra de endereço também é um campo de entrada de pesquisa. Assim, a linha de execução de interface precisa analisar e decidir se deve enviar você a um mecanismo de pesquisa ou ao site solicitado.

Como processar entradas do usuário
Figura 1: linha de execução de IU perguntando se a entrada é uma consulta de pesquisa ou um URL

Etapa 2: iniciar o trajeto

Quando um usuário pressiona Enter, o thread de interface inicia uma chamada de rede para obter o conteúdo do site. Ícone de carregamento aparece no canto de uma guia, e o thread de rede passa por protocolos adequados, como Busca DNS e estabelecimento de conexão TLS para a solicitação.

Início da navegação
Figura 2: a sequência da interface se comunicando com a sequência da rede para navegar até mysite.com

Nesse ponto, o thread de rede pode receber um cabeçalho de redirecionamento do servidor, como HTTP 301. Nesse caso, o thread de rede se comunica com o thread de IU que o servidor está solicitando o redirecionamento. Depois, outra solicitação de URL será iniciada.

Etapa 3: ler a resposta

Resposta HTTP
Figura 3: cabeçalho de resposta que contém Content-Type e payload, que são os dados reais

Quando o corpo da resposta (payload) começa a chegar, a linha de execução de rede examina os primeiros bytes do stream, se necessário. O cabeçalho "Content-Type" da resposta deve informar o tipo dos dados, mas como ela pode estar ausente ou errada, Interceptação de tipo MIME é feito aqui. Esse é um "negócio complicado" como comentado no código-fonte. Leia o comentário para saber como diferentes navegadores tratam os pares de tipo de conteúdo/payload.

Se a resposta for um arquivo HTML, a próxima etapa será transmitir os dados ao renderizador. mas se for um arquivo zip ou outro arquivo, isso significa que é uma solicitação de download, portanto, eles precisam passar os dados para o gerenciador de downloads.

Interceptação de tipo MIME
Figura 4: thread de rede perguntando se os dados de resposta são HTML de um site seguro

Também é nesse momento que ocorre a verificação de SafeBrowsing. Se o domínio e os dados de resposta parecerem corresponder a um site malicioso conhecido, o thread da rede alertas para exibir uma página de aviso. Além disso, Boxamento r read Cross (CORB) é feita para garantir que informações confidenciais entre sites dados não chegam ao processo do renderizador.

Etapa 4: encontrar um processo do renderizador

Assim que todas as verificações forem concluídas e o thread da rede tiver certeza de que o navegador navegará até a site solicitado, o thread de rede informa ao thread de IU que os dados estão prontos. Em seguida, a linha de execução de IU encontra uma para dar continuidade à renderização da página da Web.

Encontrar processo do renderizador
Figura 5: linha de execução de rede informando à linha de execução de interface para encontrar o processo do renderizador

Como a solicitação de rede pode levar várias centenas de milissegundos para receber uma resposta, um otimização para acelerar esse processo. Quando a sequência de interface está enviando uma solicitação de URL para conversa da rede na etapa 2, ele já sabe para qual site está navegando. A linha de execução de interface tenta localizar ou iniciar proativamente um processo de renderizador em paralelo à solicitação de rede. Assim, se tudo correr conforme o esperado, um processo de renderizador já estará em posição de espera quando a linha de execução de rede e os dados recebidos. Esse processo de espera pode não ser usado se a navegação redirecionar entre sites, em caso em que um processo diferente pode ser necessário.

Etapa 5: navegação de confirmação

Agora que os dados e o processo do renderizador estão prontos, uma IPC é enviada do processo do navegador para a do renderizador para confirmar a navegação. Ele também transmite o fluxo de dados para que o renderizador pode continuar recebendo dados HTML. Quando o processo do navegador receber a confirmação de que o commit ocorreu no processo do renderizador, a navegação está concluída e a fase de carregamento do documento começa.

Neste ponto, a barra de endereço é atualizada e o indicador de segurança e a interface de configurações do site refletem informações do site da nova página. O histórico de sessões da guia será atualizado para voltar/avançar. vão passar pelo site que acabou de ser acessado. Para facilitar a restauração de guias/sessões quando você fecha uma guia ou janela, o histórico da sessão é armazenado no disco.

Confirmar navegação
Figura 6: IPC entre o navegador e os processos do renderizador, solicitando a renderização da página

Etapa extra: carregamento inicial concluído

Após o commit da navegação, o processo do renderizador continua carregando recursos e renderiza os página. Na próxima postagem, vamos conferir os detalhes do que acontece nessa fase. Depois que o renderizador processo "termina" durante a renderização, ele envia uma IPC de volta ao processo do navegador (afinal de contas, Os eventos onload foram disparados em todos os frames na página e terminaram a execução. Neste ponto, a linha de execução da interface interrompe o ícone de carregamento na guia.

Digo "conclui", porque o JavaScript do lado do cliente ainda pode carregar recursos adicionais e renderizar novas visualizações após esse ponto.

Carregamento da página
Figura 7: IPC do renderizador para o processo do navegador para notificar que a página foi "carregada"

A navegação simples foi concluída! Mas o que acontece se um usuário colocar um URL diferente na barra de endereço novamente? O processo do navegador passa pelas mesmas etapas para navegar até o site diferente. Mas, antes que possa fazer isso, ele precisa verificar com o site renderizado no momento se eles se importam com evento beforeunload.

beforeunload pode criar a mensagem "Sair deste site?" quando você tentar sair ou fechar a guia. Tudo o que está dentro de uma guia, inclusive o código JavaScript, é processado pelo processo do renderizador. Portanto, o processo do navegador precisa verificar com o processo do renderizador atual quando uma nova solicitação de navegação é recebida.

manipulador de eventos beforeunload
Figura 8: IPC do processo do navegador para um processo do renderizador informando que está prestes a acessar outro site

Se a navegação foi iniciada a partir do processo do renderizador (como o usuário clicou em um link ou o JavaScript do lado do cliente executou window.location = "https://newsite.com"), o processo do renderizador primeiro verifica os gerenciadores beforeunload. Depois, ele passa pelo mesmo processo do navegador navegação iniciada. A única diferença é que a solicitação de navegação é iniciada no do renderizador ao processo do navegador.

Quando a nova navegação é feita para um site diferente daquele que está renderizado no momento, uma nova navegação é chamado para lidar com a nova navegação enquanto o processo de renderização atual é mantido para processar eventos como unload. Para mais informações, consulte Visão geral dos estados do ciclo de vida da página. e como agregar eventos com a API Page Lifecycle.

nova navegação e descarregamento
Figura 9: duas IPCs de um processo de navegador para um novo processo de renderização instruindo a renderizar a página e informar ao processo antigo do renderizador para descarregar

No caso de Service Worker

Uma alteração recente nesse processo de navegação é a introdução do service worker. O service worker é uma maneira de escrever proxy de rede no código do aplicativo. permitindo que os desenvolvedores Web tenham mais controle sobre o que armazenar em cache localmente e quando acessar novos dados da rede. Se o service worker estiver configurado para carregar a página do cache, não há necessidade de solicitar os dados da rede.

O importante a ser lembrado é que o service worker é o código JavaScript executado em um renderizador de desenvolvimento de software. Mas, quando a solicitação de navegação chega, como o processo do navegador sabe que o site tem um service worker?

Pesquisa de escopo do service worker
Figura 10: a linha de execução de rede no processo do navegador que procura o escopo do service worker

Quando um service worker é registrado, o escopo dele é mantido como referência (você pode ler mais sobre escopo neste o artigo Ciclo de vida do Service Worker). Quando ocorre uma navegação, a linha de execução de rede verifica o domínio no service worker registrado escopos, se um service worker estiver registrado para esse URL, a linha de execução de interface encontrará um processo de renderizador em para executar o código do service worker. O service worker pode carregar dados do cache, eliminando a necessidade de solicitar dados da rede ou pode solicitar novos recursos da rede.

navegação do service worker
Figura 11: a linha de execução de interface em um processo do navegador iniciando um processo de renderizador para tratar de serviços trabalhadores; uma linha de execução de worker em um processo do renderizador e solicita dados da rede

É possível perceber que essa ida e volta entre o processo do navegador e o do renderizador pode causar atrasos. se o service worker decidir solicitar dados da rede. O pré-carregamento de navegação é um mecanismo para acelerar esse carregando recursos em paralelo com a inicialização do service worker. Ele marca essas solicitações com um cabeçalho, permitindo que os servidores decidam enviar conteúdos diferentes para essas solicitações. por exemplo, dados atualizados em vez de um documento completo.

Pré-carregamento de navegação
Figura 12: a linha de execução de interface em um processo de navegador iniciando um processo de renderizador para tratar de serviços worker ao iniciar a solicitação de rede em paralelo

Conclusão

Nesta postagem, vimos o que acontece durante uma navegação e como o código do aplicativo da Web já que os cabeçalhos de resposta e o JavaScript do cliente interagem com o navegador. Conhecer o navegador de etapas faz para obter dados da rede, torna mais fácil entender por que as APIs, como a navegação, pré-carregamento foram desenvolvidos. Na próxima postagem, veremos como o navegador avalia nosso HTML/CSS/JavaScript para renderizar páginas.

Você gostou da postagem? Se você tiver dúvidas ou sugestões para a próxima postagem, será um prazer ajudar deixe você na seção de comentários abaixo ou com @kosamari no Twitter.

Próximo: funcionamento interno de um processo de renderizador