
⚡ Contact form 7 - carregamento diferido de scripts e estilos para acelerar o WordPress
Como o CF7 torna o seu site mais lento e porque pode resolver isso em 5 minutos
O Contact Form 7 está instalado em mais de 5 milhões de sites WordPress. O plugin é fiável, flexível e gratuito, e os formulários de contacto criados com ele funcionam em praticamente todos os sites. Mas esta conveniência tem um lado negativo: por predefinição, o CF7 carrega o seu CSS e JavaScript em todas as páginas do seu site, mesmo quando não há nenhum formulário por perto.
Para a página inicial, blogue, páginas de destino e dezenas de outras páginas, isto é peso morto: pedidos extra, aumento do DOM Content Loaded, tamanho de página inchado. Em números, cerca de 10 a 30 KB de tráfego comprimido e 1 a 2 pedidos bloqueantes sem motivo algum. O PageSpeed Insights não perdoa estas coisas.
Isto pode ser resolvido de três formas, desde um simples defer de duas linhas até ao carregamento condicional cuidadoso e «within the book» do criador do plugin. Vamos abordar cada uma, com código e sem palha.
💡 Visão geral rápida:
- Desative o carregamento global do CF7 através das constantes
WPCF7_LOAD_JSeWPCF7_LOAD_CSSnowp-config.php, o método oficial mais limpo. - Reative os scripts e estilos, mas apenas nas páginas com um formulário, através de
wpcf7_enqueue_scripts()no modelo de página. - Para pacotes personalizados, o pacote
lazy-cf7-assets, que encontra automaticamente o formulário na página e carrega o JS dinamicamente.
Método 1: adiar o carregamento do script do CF7 via functions.php
A opção mais rápida e simples é adicionar o atributo defer ao script do Contact Form 7. Isto diz ao navegador: «carrega o ficheiro em segundo plano, mas executa-o quando o DOM estiver pronto». O formulário continua a funcionar, mas o script deixa de bloquear a renderização da página.
Adicione este código ao functions.php no seu tema ativo (ou através do plugin Code Snippets, mais seguro durante as atualizações):
1 if ( ! function_exists( 'add_defer_to_cf7' ) ) { 2 function add_defer_to_cf7( $url ) { 3 if ( 4 false === strpos( $url, 'contact-form-7' ) || 5 false === strpos( $url, '.js' ) 6 ) { 7 return $url; 8 } 9 return "$url' defer='defer"; 10 } 11 add_filter( 'clean_url', 'add_defer_to_cf7', 11, 1 ); 12 }
A função verifica o URL de cada script registado através do hook clean_url. Se o endereço contiver contact-form-7 e a extensão .js, adiciona defer='defer'. Todos os outros scripts são deixados como estão.
Vantagem: uma solução em 10 linhas que não requer a edição de modelos ou da configuração do plugin. Adequado para temas onde não existe um modelo de página de contacto separado.
Desvantagem: o script continua a carregar em todas as páginas, está apenas a remover o comportamento de bloqueio de renderização. O tráfego e os pedidos ao servidor não são reduzidos. Este método não afeta de todo o CSS do plugin, a folha de estilos carrega como habitualmente.
Método 2: método oficial, carregamento condicional através de constantes
Esta abordagem está descrita na documentação do Contact Form 7 pelo próprio criador do plugin, Takayuki Miyoshi. A ideia tem dois passos: primeiro, desative globalmente os scripts e estilos do CF7 e, depois, reative-os, mas apenas nas páginas onde o formulário é realmente utilizado.
Passo 1: desativar o carregamento em todas as páginas
Adicione duas constantes ao wp-config.php:
1 define( 'WPCF7_LOAD_JS', false ); 2 define( 'WPCF7_LOAD_CSS', false );
Em alternativa, através do functions.php do seu tema:
1 add_filter( 'wpcf7_load_js', '__return_false' ); 2 add_filter( 'wpcf7_load_css', '__return_false' );
Depois disto, o CF7 não carregará uma única linha do seu código em nenhuma página do seu site, incluindo aquelas onde existe um formulário. Sem scripts, o formulário perde a submissão por AJAX e a validação, pelo que o passo 2 é necessário.
Passo 2: restaurar os scripts nas páginas com um formulário
Suponhamos que a sua página de contacto usa o template page-contact.php na pasta do seu tema. Adicione isto a esse template antes de chamar wp_head():
1 if ( function_exists( 'wpcf7_enqueue_scripts' ) ) { 2 wpcf7_enqueue_scripts(); 3 } 4 5 if ( function_exists( 'wpcf7_enqueue_styles' ) ) { 6 wpcf7_enqueue_styles(); 7 }
As funções wpcf7_enqueue_scripts() e wpcf7_enqueue_styles() carregam manualmente os scripts e estilos do CF7 apenas neste template. Todas as outras páginas do seu site permanecem limpas.
Vantagem: o método é «do fabricante», garantido que não se parte durante as atualizações do plugin. Funciona com as versões 5.x e 6.x do CF7, versão atual 6.1.6 em junho de 2026 (lista de versões). Zero carregamentos desnecessários em páginas sem formulário.
Desvantagem: requer a edição dos templates do tema. Se tiver várias páginas com formulários, precisa de se lembrar de adicionar as chamadas a cada template. Se o formulário for inserido via shortcode no conteúdo (em vez de num template), o método não funcionará sem condições adicionais.
Método 3: o pacote lazy-cf7-assets para bundles de JavaScript
Se estiver a construir o seu frontend com um bundler (Webpack, Vite, esbuild) e a usar um tema moderno com um bundle de JavaScript personalizado, existe um pacote npm chamado lazy-cf7-assets. Ele resolve o mesmo problema, mas do lado do cliente: faz scan ao DOM, encontra o formulário do CF7 e só então carrega dinamicamente os scripts do plugin.
Instalação:
1 npm install lazy-cf7-assets
Antes de o usar, precisa de desativar o carregamento automático de JS pelo plugin (como no método 2, via wpcf7_load_js):
1 add_filter( 'wpcf7_load_js', '__return_false' );
Depois, no seu bundle de JS:
1 import lazyform from 'lazy-cf7-assets'; 2 3 // Initialize after DOM ready 4 lazyform.init();
Se os scripts carregarem no <head> em vez de no final do <body>, especifique um caminho absoluto para a imagem GIF de carregamento para que o formulário não «pisque» num estado vazio:
1 lazyform.init({ 2 gifPath: '/wp-content/themes/my-theme/images/ajax-loader.gif' 3 });

Vantagem: zero intervenção no lado do PHP, sem necessidade de editar templates para cada página com formulário. O pacote deteta automaticamente se existe um shortcode do CF7 na página e carrega os scripts apenas nesse caso. Adequado para sites onde o formulário é apresentado via shortcode no conteúdo (em vez de estar hardcoded num template).
Desvantagem: funciona apenas com JavaScript (o CSS do plugin ainda precisa de ser desativado separadamente). Requer um bundler no projeto. O pacote é mínimo (1 estrela no GitHub), mantido por um único developer; para produção, deve fazer fork e verificar a compatibilidade com as atualizações do CF7.
O que escolher: comparação das três abordagens
Critério | defer via hook | Constantes + template | lazy-cf7-assets |
|---|---|---|---|
Poupança de tráfego | ❌ não | ✅ total | ✅ total (JS) |
Proteção contra atualizações do CF7 | ✅ sim | ✅ sim | requer verificação |
Não requer edição de templates | ✅ sim | ❌ não | ✅ sim |
Desativa o CSS | ❌ não | ✅ sim | ❌ não |
Complexidade de implementação | baixa | média | média |
Shortcode do formulário no conteúdo | ✅ funciona | ❌ dificuldades | ✅ funciona |
Se o seu formulário reside numa única página, num template separado, use o método 2 (método oficial). Se o site usa um bundler moderno e pode ter vários formulários em locais diferentes, o método 3 (lazy-cf7-assets). Se precisa de uma solução «para já» sem editar templates, o método 1 (defer), mas lembre-se das limitações.
Uma ressalva importante: após qualquer uma destas alterações, certifique-se de verificar que o formulário submete, a validação funciona, o reCAPTCHA não está partido e os estilos não se deslocaram. Abra a página com o formulário em modo anónimo, preencha e submeta uma mensagem de teste antes e depois.
⁉️🤔 Perguntas frequentes
Porque é que o CF7 carrega scripts em todas as páginas, de qualquer forma?
O plugin não sabe, na fase de carregamento do WordPress, se uma página específica contém um shortcode de formulário. O WordPress monta a página mais tarde, quando a fila de scripts já foi formada. O programador Takayuki Miyoshi explica isto na documentação oficial: é tecnicamente impossível detetar a presença de um shortcode antes do hook
wp_head. Por isso, foi escolhida uma abordagem conservadora, de carregar sempre. Esta é uma decisão arquitetural deliberada, não um bug: o plugin sacrifica o desempenho em prol da funcionalidade garantida. O ónus da otimização é transferido para o programador do site.
O formulário vai deixar de funcionar depois de desativar o carregamento global?
Não, se reativar cuidadosamente os scripts nas páginas necessárias. O formulário perderá o envio por AJAX e a validação do lado do cliente apenas nas páginas onde os scripts não forem incluídos. É por isso que o passo 2 (restaurar os scripts) é obrigatório, não pare apenas em
WPCF7_LOAD_JS = false. Verifique a ordem das chamadas:wpcf7_enqueue_scripts()deve vir antes dewp_head(), e não depois. E certifique-se de que o reCAPTCHA não entra em conflito com o carregamento diferido.
O método das constantes funciona com o CF7 6.x?
Sim, as constantes
WPCF7_LOAD_JSeWPCF7_LOAD_CSSsão totalmente suportadas na versão atual 6.1.6 (consulte o registo oficial de versões). Ao longo de toda a história do plugin, da versão 3.9 até à atual 6.x, estas constantes nunca foram declaradas como obsoletas. Este é o método mais estável e documentado para gerir o carregamento.
E se eu tiver vários formulários em locais diferentes?
Se os formulários estiverem dispersos por páginas diferentes através de shortcodes no conteúdo (e não em modelos), o método oficial com modelos é inconveniente. Use o
lazy-cf7-assets(método 3) ou o plugin Conditionally Load CF7: ele adiciona uma configuração no painel de administração para definir em que páginas ou tipos de conteúdo os scripts devem ser carregados, e funciona sem edição de código.
Três linhas de código contra dezenas de pedidos
O problema de "o CF7 carrega scripts em todo o lado" existe exatamente há tanto tempo quanto o próprio plugin e, ao longo de mais de 10 anos, o programador não alterou o comportamento padrão, porque é um compromisso entre simplicidade e desempenho. Mas um compromisso, não uma sentença.
O caminho mais seguro é o método oficial com constantes e modelos. Ele remove os scripts e estilos do plugin de todas as páginas, exceto daquelas onde são necessários, e não se quebra durante as atualizações. Se o seu site usa uma stack moderna com um bundler, dê uma vista de olhos ao lazy-cf7-assets. Se precisa de algo rápido e sem editar modelos, o carregamento diferido através do hook clean_url dar-lhe-á melhorias nas métricas hoje mesmo.
Verifique o seu site através do PageSpeed Insights antes e depois; reduzir o número de pedidos bloqueantes em 1 ou 2 unidades e poupar 10 a 30 KB por página pode aumentar a pontuação de Desempenho em 2 a 5 pontos, especialmente em dispositivos móveis.



