Os scripts de terceiros afetam a performance. Por isso, é importante fazer auditorias regulares e usar técnicas eficientes para carregá-los. Este codelab mostra como otimizar o carregamento de recursos de terceiros. Ele aborda as seguintes técnicas:
Adiando o carregamento do script
Carregamento lento de recursos não críticos
Pré-conexão às origens necessárias
O app de exemplo incluso tem uma página da Web simples com três recursos de fontes externas:
Um vídeo incorporado
Uma biblioteca de visualização de dados para renderizar um gráfico de linhas
Um widget de compartilhamento em redes sociais
Você vai começar medindo o desempenho do app e, em seguida, vai aplicar cada técnica para melhorar diferentes aspectos dele.
Avaliar o desempenho
Primeiro, abra o app de exemplo na visualização em tela cheia:
- Clique em Remixar para editar para tornar o projeto editável.
- Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia .
Faça uma auditoria de desempenho do Lighthouse na página para estabelecer o valor de referência:
- Pressione "Control + Shift + J" (ou "Command + Option + J" no Mac) para abrir o DevTools.
- Clique na guia Lighthouse.
- Clique em Dispositivo móvel.
- Marque a caixa de seleção Desempenho. Você pode desmarcar o restante das caixas de seleção na seção Auditorias.
- Clique em Simulado 3G rápido, 4x lentidão da CPU.
- Marque a caixa de seleção Limpar armazenamento.
- Clique em Executar auditorias.
Ao fazer uma auditoria na sua máquina, os resultados exatos podem variar, mas você vai perceber que o tempo da Primeira exibição de conteúdo (FCP, na sigla em inglês) é muito alto, e o Lighthouse sugere duas oportunidades de investigação: Eliminar recursos de bloqueio de renderização e Pré-conectar às origens necessárias. Mesmo que todas as métricas estejam em verde, as otimizações ainda produzirão melhorias.
Adiar o JavaScript de terceiros
A auditoria Eliminar recursos de bloqueio de renderização identificou que é possível economizar tempo adiando um script proveniente de d3js.org:
O D3.js é uma biblioteca JavaScript para criar visualizações de dados. O arquivo script.js
no app de exemplo usa funções utilitárias do D3 para criar o gráfico de linhas SVG e anexá-lo à página. A ordem das operações é importante: o script.js
precisa ser executado depois que o documento for analisado e a biblioteca D3 for carregada. Por isso, ela é incluída logo antes da tag de fechamento </body>
no index.html
.
No entanto, o script D3 está incluído no <head>
da página, que bloqueia a análise do restante do documento:
Dois atributos mágicos podem desbloquear o analisador quando adicionado à tag de script:
O
async
garante que o download dos scripts seja feito em segundo plano e executado na primeira oportunidade após o download.O
defer
garante que o download dos scripts seja concluído em segundo plano e executado depois da análise.
Como esse gráfico não é muito importante para a página geral e provavelmente vai ficar abaixo da dobra, use defer
para garantir que não haja bloqueio do analisador.
Etapa 1: carregar o script de forma assíncrona com o atributo defer
Na linha 17 em index.html
, adicione o atributo defer
ao elemento <script>
:
<script src="https://d3js.org/d3.v3.min.js" defer></script>
Etapa 2: garantir a ordem correta das operações
Agora que o D3 foi adiado, o script.js
vai ser executado antes que o D3 esteja pronto, resultando em um erro.
Os scripts com o atributo defer
são executados na ordem em que foram especificados. Para garantir que o script.js
seja executado depois que a D3 estiver pronta, adicione defer
a ela e mova-a para o <head>
do documento, logo após o elemento <script>
do D3. Agora, o analisador não é mais bloqueado, e o download começa antes.
<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>
Recursos de terceiros com carregamento lento
Todos os recursos abaixo da dobra são bons candidatos para o carregamento lento.
O app de exemplo tem um vídeo do YouTube incorporado em um iframe. Para conferir quantas solicitações a página faz e quais vêm do iframe do YouTube incorporado:
- Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia .
- Pressione "Control + Shift + J" (ou "Command + Option + J" no Mac) para abrir o DevTools.
- Clique na guia Rede.
- Marque a caixa de seleção Desativar cache.
- Selecione 3G rápido no menu suspenso Limitação.
- Recarregue a página.
O painel Rede revela que a página fez um total de 28 solicitações e transferiu quase 1 MB de recursos compactados.
Para identificar as solicitações feitas pelo iframe
do YouTube, procure o ID do vídeo 6lfaiXM6waw
na coluna Iniciador. Para agrupar todas as solicitações por domínio:
No painel Rede, clique com o botão direito do mouse no título de uma coluna.
No menu suspenso, selecione a coluna Domínios.
Para classificar as solicitações por domínio, clique no título da coluna Domínios.
A nova classificação revela que há solicitações adicionais aos domínios do Google. No total, o iframe do YouTube faz 14 solicitações de scripts, folhas de estilo, imagens e fontes. Mas, a menos que os usuários rolem a tela para baixo para reproduzir o vídeo, eles não precisam de todos esses recursos.
Ao aguardar o carregamento lento do vídeo até que o usuário role para baixo até essa seção da página, você reduz o número de solicitações feitas pela página inicialmente. Essa abordagem salva os dados dos usuários e acelera o carregamento inicial.
Uma maneira de implementar o carregamento lento é usando a Intersection Observer, uma API do navegador que notifica quando um elemento entra ou sai da janela de visualização do navegador.
Etapa 1: impedir que o vídeo seja carregado inicialmente
Para carregar lentamente o iframe de vídeo, primeiro é preciso impedir que ele seja carregado da maneira normal. Para isso, substitua o atributo src
por data-src
para especificar o URL do vídeo:
<iframe width="560" height="315" data-src="https://www.youtube.com/embed/lS9D6w1GzGY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
O data-src
é um atributo de dados que permite armazenar informações extras sobre elementos HTML padrão. Um atributo de dados pode ter qualquer nome, desde que comece com "data-".
Um iframe sem um src
simplesmente não é carregado.
Etapa 2: usar o Intersection Observer para carregar o vídeo lentamente
Para carregar o vídeo quando um usuário rola até ele, você precisa saber quando isso acontece. É aí que entra a API Intersection Observer. A API Intersection Observer permite registrar uma função de callback que é executada sempre que um elemento que você quer rastrear entra ou sai da janela de visualização.
Para começar, crie um novo arquivo e nomeie-o como lazy-load.js
:
- Clique em Novo arquivo e atribua um nome a ele.
- Clique em Adicionar este arquivo.
Adicione a tag de script ao cabeçalho do documento:
<script src="/lazy-load.js" defer></script>
Em lazy-load.js
, crie um novo IntersectionObserver
e transmita a ele uma função de callback para execução:
// create a new Intersection Observer
let observer = new IntersectionObserver(callback);
Agora forneça à observer
um elemento de destino para assistir (o iframe de vídeo, neste caso), transmitindo-o como um argumento no método observe
:
// the element that you want to watch
const element = document.querySelector('iframe');
// register the element with the observe method
observer.observe(element);
O callback
recebe uma lista de objetos IntersectionObserverEntry
e o próprio objeto IntersectionObserver
. Cada entrada contém um elemento target
e propriedades que descrevem as dimensões, a posição, o horário de entrada na janela de visualização e muito mais. Uma das propriedades de IntersectionObserverEntry
é isIntersecting
, um valor booleano que é igual a true
quando o elemento entra na janela de visualização.
Neste exemplo, o target
é o iframe
. isIntersecting
é igual a true
quando target
entra na janela de visualização. Para ver isso em ação, substitua callback
pela seguinte função:
let observer = new IntersectionObserver(callback);
let observer = new IntersectionObserver(function(entries, observer) {
entries.forEach(entry => {
console.log(entry.target);
console.log(entry.isIntersecting);
});
});
- Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia .
- Pressione "Control + Shift + J" (ou "Command + Option + J" no Mac) para abrir o DevTools.
- Clique na guia Console.
Tente rolar para cima e para baixo. Você verá o valor de isIntersecting
mudar e o elemento de destino será registrado no console.
Para carregar o vídeo quando o usuário rolar até a posição, use isIntersecting
como condição para executar uma função loadElement
, que recebe o valor do data-src
do elemento iframe
e o define como o atributo src
do elemento iframe
. Essa substituição aciona o carregamento do vídeo. Em seguida, assim que o vídeo for carregado, chame o método unobserve
no observer
para parar de assistir ao elemento de destino:
let observer = new IntersectionObserver(function (entries, observer) {
entries.forEach(entry => {
console.log(entry.target);
console.log(entry.isIntersecting);
});
});
if (entry.isIntersecting) {
// do this when the element enters the viewport
loadElement(entry.target);
// stop watching
observer.unobserve(entry.target);
}
});
});
function loadElement(element) {
const src = element.getAttribute('data-src');
element.src = src;
}
Etapa 3: reavalie a performance
Para ver como o tamanho e o número de recursos mudaram, abra o painel Network do DevTools e atualize a página novamente. O painel Rede revela que a página fez 14 solicitações e apenas 260 KB. É uma melhoria significativa.
Role a página para baixo e observe o painel Rede. Ao acessar o vídeo, você verá a página acionar solicitações adicionais.
Pré-conexão às origens necessárias
Você adiou o JavaScript não crítico e carregou lentamente as solicitações do YouTube, então agora é hora de otimizar o conteúdo de terceiros restante.
Adicionar o atributo rel=preconnect
a um link instrui o navegador a estabelecer uma conexão com um domínio antes que a solicitação desse recurso seja feita. Esse atributo é melhor usado em origens que fornecem recursos aos quais você tem certeza de que a página precisa.
A auditoria do Lighthouse que você executou na primeira etapa sugeriu em Pré-conectar às origens necessárias que você pode salvar cerca de 400 ms estabelecendo conexões antecipadas com estáticoxx.facebook.com e youtube.com:
Como o vídeo do YouTube agora tem carregamento lento, resta apenas estáticoxx.facebook.com, a origem do widget de compartilhamento de mídia social. Para estabelecer uma conexão inicial com esse domínio, basta adicionar uma tag <link>
ao <head>
do documento:
<link rel="preconnect" href="https://staticxx.facebook.com">
Reavalie a performance
Veja o estado da página após a otimização. Siga as etapas da seção Medir o desempenho do codelab para executar outra auditoria do Lighthouse.