Privacidade Por Equipe DevBras

Capa do artigo: SDK de rede social no head: o custo que a página paga e como carregar só na hora certa

SDK de rede social no head: o custo que a página paga e como carregar só na hora certa

Meça quanto o SDK social pesa, tire-o do carregamento inicial e carregue só quando a pessoa demonstrar intenção, sem bloquear o popup de login e sem script de terceiro na tela de senha.

O site da loja colou o SDK de uma rede social no template base há dois anos, "porque um dia vamos ter o login social". O botão nunca saiu do papel. Mesmo assim, cada visita à home, a cada artigo e a cada página de produto baixa o SDK, executa o script e avisa a rede de que alguém chegou. A resposta curta: sem recurso na tela, sem SDK. Onde o recurso existe, carregue o script só quando a pessoa mostrar intenção de usá-lo, como passar o mouse ou focar o botão, e nunca numa página com campo de senha.

O guia de início rápido manda colar o script logo no começo do body, para todas as páginas. É o jeito mais simples de começar e o mais caro de manter.

Por que o SDK no carregamento custa caro

O custo tem duas metades. A primeira é desempenho. O navegador precisa resolver o domínio da rede, abrir uma conexão TLS, baixar o script, interpretar e executar. Com async, o download não trava o HTML, mas a execução ainda disputa a thread principal com o seu código, e o SDK costuma buscar recursos adicionais. Em celular intermediário, numa rede 4G ruim, isso aparece como página que demora a responder ao toque.

A segunda metade é privacidade. Cada carregamento é um pedido ao domínio da rede, com IP, navegador e página de origem, e, conforme o navegador, com os cookies da conta. O SDK roda com os mesmos poderes do seu JavaScript: lê o DOM, vê o que é digitado, observa a navegação. Isso vale para qualquer script de terceiro, não por suspeita de uma empresa específica; é como o navegador funciona.

Por isso SDK social que não sustenta uma função essencial entra no controle de consentimento, como descrito em banner de cookie honesto. Os botões de curtir e compartilhar têm o seu próprio guia em botão social sem script de terceiro.

Meça antes de discutir

"Não pesa nada" é uma afirmação que se testa em dez minutos. No Chrome, abra o DevTools e rode o Lighthouse na página de artigo, em modo móvel, três vezes, anotando a mediana. Depois abra o painel de bloqueio de requisições de rede (Network request blocking), bloqueie o domínio do SDK, recarregue e rode de novo. Compare tempo de carregamento, tempo total de bloqueio e bytes transferidos.

No blog da loja, a página de artigo transferia 410 KB; com o SDK bloqueado, caiu para 190 KB, e o tempo total de bloqueio da thread principal caiu pela metade. Os números do seu site serão outros. O que importa é que existam, porque a decisão passa de opinião para medida. Para encaixar isso numa lista mais ampla de otimizações, veja site mais rápido: por onde começar.

Como carregar o SDK só na hora certa

  1. Tire o script do template base. Busque o domínio do SDK em todos os templates e remova.
  2. Liste as páginas com recurso real. Se o login social existe só na tela de entrar, o SDK só pode existir lá, e talvez nem lá.
  3. Carregue na intenção. Ao passar o mouse, focar com o teclado ou tocar no botão, comece o download.
  4. Chame o login no clique, de forma síncrona. Navegadores bloqueiam popup que não nasce direto de um gesto do usuário. Se o SDK ainda não carregou no clique, mostre "carregando" e peça um segundo clique.
  5. Trate a falha. Bloqueador de anúncios, rede corporativa e erro de DNS derrubam o SDK. O botão precisa avisar, não sumir em silêncio.
  6. Valide no servidor. O token recebido no navegador precisa ser conferido pelo seu backend antes de criar sessão.

Exemplo: carregamento por intenção

O botão guarda o id do app e a versão da API configurada no painel da rede:

<button type="button" data-login-social
        data-app-id="SEU_APP_ID" data-versao-api="VERSAO_DO_PAINEL">
  Continuar com a rede social
</button>
const botao = document.querySelector('[data-login-social]');
let carregamento = null;
let sdk = null;

function carregarSdk() {
  if (carregamento) return carregamento;
  carregamento = new Promise((resolve, reject) => {
    window.fbAsyncInit = () => {
      window.FB.init({
        appId: botao.dataset.appId,
        version: botao.dataset.versaoApi,
        xfbml: false
      });
      sdk = window.FB;
      resolve(sdk);
    };
    const s = document.createElement('script');
    s.src = 'https://connect.facebook.net/pt_BR/sdk.js';
    s.async = true;
    s.crossOrigin = 'anonymous';
    s.onerror = () => {
      carregamento = null;
      s.remove();
      reject(new Error('SDK indisponível'));
    };
    document.head.appendChild(s);
  });
  return carregamento;
}

function preaquecer() {
  carregarSdk().catch(() => {});
}

['pointerenter', 'focus', 'touchstart'].forEach((evento) => {
  botao.addEventListener(evento, preaquecer, { once: true, passive: true });
});

async function tratarResposta(resposta) {
  if (resposta.status !== 'connected') return;
  try {
    const r = await fetch('/auth/rede-social', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ accessToken: resposta.authResponse.accessToken })
    });
    if (!r.ok) throw new Error('Servidor recusou o login: ' + r.status);
    location.assign('/minha-conta');
  } catch (err) {
    console.error(err);
    botao.textContent = 'Não foi possível entrar. Tente de novo.';
  }
}

botao.addEventListener('click', () => {
  if (sdk) {
    sdk.login((resposta) => { tratarResposta(resposta); }, { scope: 'public_profile,email' });
    return;
  }
  botao.disabled = true;
  botao.textContent = 'Carregando...';
  carregarSdk()
    .then(() => { botao.textContent = 'Clique para continuar com a rede social'; })
    .catch(() => { botao.textContent = 'Login social indisponível agora'; })
    .finally(() => { botao.disabled = false; });
});

Na prática, quem chega ao botão com mouse ou teclado dispara o download alguns centésimos de segundo antes do clique, e o login abre direto. O caminho do "segundo clique" é a rede de segurança para quem foi rápido demais ou está numa conexão lenta. No servidor, o token precisa ser validado junto à rede antes de virar sessão; os detalhes estão em login do Facebook não cria sozinho a sessão.

Por que nada de SDK na página com senha

Se a tela de entrar tem o campo de senha da sua conta própria e também o botão social, o SDK carregado ali tem acesso técnico ao que é digitado no formulário. Mesmo confiando no fornecedor, você aumenta a superfície: qualquer comprometimento desse script vira leitura de senha. A alternativa mais limpa é o fluxo por redirecionamento: o botão é um link para uma rota do seu servidor, que manda a pessoa à tela de autorização da rede e recebe o código de volta. A própria documentação de login da rede descreve como montar esse fluxo manualmente, e o padrão é o mesmo explicado em login web com PKCE. Nenhum script de terceiro precisa rodar na sua página.

Erros comuns

  • SDK no template base "para o futuro". Todas as páginas pagam o custo de um recurso que não existe.
  • Chamar o login depois de um await longo. O navegador não reconhece mais o gesto do usuário e bloqueia o popup.
  • Esconder o botão quando o SDK falha. A pessoa não entende por que a opção sumiu e o suporte recebe o chamado.
  • Confiar no token só no navegador. Sem validação no servidor, qualquer um forja a resposta e entra.
  • SDK na tela com campo de senha. Um script de terceiro ganha acesso técnico à senha digitada.
  • Defender "não pesa" sem medir. A discussão fica no gosto e o script nunca sai.

Checklist

  • O domínio do SDK não aparece em nenhum template base.
  • Existe medição com e sem o SDK, com números anotados.
  • O SDK só carrega em páginas com recurso real e após intenção do usuário.
  • O login é chamado direto no clique, sem espera antes.
  • Falha de carregamento mostra mensagem e permite tentar de novo.
  • O token é validado no servidor antes de criar sessão.
  • Páginas com campo de senha não carregam script de rede social.

Abra a home do seu site com a aba Network e filtre pelos domínios das redes sociais: algum script é pedido antes de qualquer clique, e qual recurso visível na tela justifica esse pedido?

Avalie este artigo

Referência: https://developers.facebook.com/docs/javascript/quickstart