Do JavaScript da página mediana para celular no Web Almanac 2024, 168 kilobytes eram próprios e 375 kilobytes eram de terceiros.1 Mais da metade do script de uma página comum, em peso, tinha sido escrita por alguém que não o dono do site. O capítulo do Almanac sobre terceiros os encontrou em 92% das páginas, sendo o script o tipo mais comum de requisição a terceiros.2 O script de uma rede de anúncios, aquele que um editor adiciona para exibir os seus anúncios, é uma dessas requisições. O que esse script custa à página no carregamento depende menos do que ele faz do que de como está escrito o elemento que o carrega.

O navegador para diante de um elemento script que não traz nenhum atributo

Segundo o HTML Living Standard, um navegador tem três maneiras de lidar com um script externo, e elas diferem apenas por um atributo no elemento.3 A primeira, sem nenhum dos atributos, é o padrão: o script "é buscado e avaliado imediatamente, bloqueando a análise até que ambas as coisas estejam concluídas". A segunda, defer, busca o arquivo em paralelo com a análise e o avalia "quando a página terminar de ser analisada". Na terceira, async, o arquivo também é buscado em paralelo, mas avaliado "assim que estiver disponível (possivelmente antes de a análise terminar)". Só o primeiro modo segura o analisador enquanto o arquivo atravessa a rede, e nada depois do elemento é desenhado até que o arquivo chegue.

A auditoria do Lighthouse, do Google, transforma essa distinção em um teste que um editor pode fazer na própria página. Ela sinaliza um elemento script no head do documento que não traz nem defer nem async.4 O relatório "lista todas as URLs que bloqueiam a primeira pintura da sua página". O tamanho não faz parte dessa definição, nem a finalidade. Um script de análise de dados, um script de anúncios e um carregador de fontes são tratados da mesma forma se estiverem no head sem atributo.

O script de terceiros é o caso para o qual as orientações de carregamento foram escritas

As orientações do web.dev são diretas sobre scripts vindos de fora do site. Os scripts síncronos, dizem, "atrasam a construção do DOM e a renderização", sendo o DOM o modelo de trabalho que o navegador faz do documento.5 A regra que se segue é "sempre carregar scripts de terceiros de forma assíncrona, a menos que o script precise rodar antes que a página possa ser renderizada". O async serve para um script que precisa rodar cedo no processo de carregamento; o defer serve para "recursos menos críticos", e o exemplo dado é um player de vídeo abaixo da dobra. Um script de anúncio que funciona depois que o texto está na tela se enquadra, por esse teste, entre os menos críticos.

A prática se espalhou, embora não para todas as páginas. O Web Almanac 2024 encontrou async em 87% das páginas, contra 76% em 2022, e defer em 47%, contra 42%.1 Esses números descrevem as páginas como um todo. Uma página cujos próprios scripts são adiados ainda pode ter um elemento bloqueante fornecido por um terceiro. Um trecho de código de instalação, a menos que o editor o modifique, carrega da forma como a rede o escreveu.

Um script que espera o DOM não tem primeira pintura para bloquear

O navegador marca com um evento o momento em que o analisador termina de construir o DOM. Segundo a MDN, o DOMContentLoaded "é disparado quando o documento HTML foi completamente analisado e todos os scripts adiados" foram baixados e executados.6 O evento não espera imagens, subframes nem scripts async. Um script que começa o seu trabalho nesse momento, portanto, começa depois que o texto existe, sem esperar a última imagem.

O script de incorporação da AdBubbles, adbubbles.js, carrega depois que o DOM da página está pronto. É um único arquivo estático, servido pelo cache da Cloudflare e escrito em JavaScript puro, sem dependências. Os dados por site que ele lê também são um arquivo estático, gerado de novo quando uma campanha muda e armazenado em cache na borda da rede. Uma visualização de página, portanto, não custa nada ao servidor de anúncios, e a única requisição dinâmica é um pequeno beacon. O script de incorporação examina apenas o escopo que o editor configurou e ignora títulos, links, código, texto pré-formatado, controles de formulário, navegação, cabeçalho, rodapé e qualquer coisa marcada com data-noads. As notas de instalação descrevem a configuração do escopo.

Abrir uma conta de editor não custa nada, e adicionar o script de incorporação a um site também não. Um editor que adiciona um site pode solicitar um rastreamento que mostra quais das suas palavras podem ser vendidas no momento. O escopo, o máximo de bolhas por página e as categorias de anunciantes excluídas são escolhidos na mesma conta.

O beacon enviado quando um leitor sai é a outra metade do custo

O momento em que um leitor sai é a outra oportunidade de um script atrasá-lo. O código de análise de dados que fazia o seu relatório no descarregamento da página antes dependia de técnicas como "uma chamada XMLHttpRequest síncrona e bloqueante".7 A MDN registra que todos esses métodos "bloqueiam o descarregamento do documento, o que atrasa a navegação para a página seguinte". O método sendBeacon os substitui. Ele envia uma pequena requisição HTTP POST de forma assíncrona. O navegador transmite os dados "quando o agente de usuário tem oportunidade de fazê-lo, sem atrasar o descarregamento nem a navegação seguinte".

O script de incorporação faz os seus relatórios com sendBeacon e envia três tipos de beacon. Uma visualização é enviada por carregamento de página. Uma abertura é enviada quando uma bolha fica visível por um segundo, e um clique é enviado quando um leitor segue o link dentro de uma bolha. Nada mais sai da página.

A AdBubbles não define cookies, não armazena identificadores e não coleta dados pessoais dos leitores. O país do leitor é lido de um cabeçalho de requisição da Cloudflare, e não de um endereço IP armazenado. Associar palavras das páginas de um editor ao anunciante que as comprou é tudo o que a AdBubbles faz. A AdBubbles não tem nenhuma participação na escolha de quais pessoas veem uma bolha, nunca segue um leitor de uma página ou de um site para o seguinte e não promete nenhum resultado. A posição sobre privacidade está publicada por completo.

Os navegadores agora contam o que um anúncio custa e agem com base no total

A Heavy Ad Intervention do Chrome mostra o que um fabricante de navegador considera excessivo. Um anúncio só é considerado pesado "se o usuário não interagiu com ele (por exemplo, não tocou nem clicou nele)".8 Além disso, basta qualquer um de três limites. O primeiro é mais de 4 megabytes de largura de banda de rede. O segundo é mais de 15 segundos de tempo da thread principal em qualquer janela de 30 segundos, e o terceiro é mais de 60 segundos no total.

Quando a intervenção é acionada, o conteúdo do frame do anúncio é "substituído por uma mensagem de Anúncio removido", e o mecanismo age sobre iframes marcados como anúncio.8 A medida é feita em bytes e em tempo da thread principal; o conteúdo do anúncio não tem papel algum. Uma bolha é renderizada dentro de um Shadow DOM no próprio documento do editor, e não em um iframe, então esse mecanismo se dirige a outro tipo de anúncio. O que o script de incorporação acrescenta a uma determinada página, em bytes e em tempo da thread principal, é algo que as medições da própria página vão mostrar.

A verificação que um editor pode fazer na própria página não exige nada além de um navegador. O código-fonte da página lista todos os elementos script do head, e cada um traz async ou defer ou não traz nenhum dos dois. A seção Oportunidades do Lighthouse lista os que não trazem nenhum como URLs que bloqueiam a primeira pintura.4 O trecho de código de uma rede que aparece nessa lista está bloqueando a página segundo a definição do padrão, diga o que disser a documentação da rede sobre o seu peso. Se um script de anúncio entra nessa lista é decidido pelo atributo no seu elemento, e o atributo é escrito no trecho de código antes que qualquer editor o cole.