Há um momento pelo qual todas as lojas WooCommerce passam. É por volta de €500 mil em receita anual, ou alguns milhares de produtos ativos, ou uma campanha de alto tráfego que quebra algo que ninguém detetou em desenvolvimento.
A loja deixa de parecer rápida. As páginas de carrinho demoram três segundos. O abandono no checkout dispara. O alojamento diz “precisa de mais recursos” e apresenta-lhe um plano mais caro. O PageSpeed Insights pinta tudo de vermelho.
Mais recursos raramente resolvem o problema subjacente. O que resolve: saber onde o WooCommerce fica especificamente lento à escala, e quais são os sete fatores que são quase sempre os verdadeiros culpados.
O padrão
Uma loja WooCommerce pequena é maioritariamente cacheável. Os visitantes chegam a uma página de categoria (em cache), navegam pelos produtos (em cache), adicionam ao carrinho (não cacheável a partir daqui), fazem o checkout e saem. As páginas em cache cobrem mais de 90% do tráfego e o fluxo de carrinho/checkout, não cacheável, trata uma pequena minoria de pedidos com rapidez suficiente.
À escala, duas coisas mudam. Primeiro, o catálogo cresce — mais produtos, mais variações, mais termos de taxonomia, consultas maiores. Segundo, a proporção de tráfego de carrinho/checkout aumenta porque as taxas de conversão são relativamente estáveis e adicionou zeros à contagem de visitantes. A parte não cacheável do seu site torna-se o gargalo.
Eis o que realmente falha, aproximadamente pela ordem em que o encontro nas auditorias.
1. Sobrecarga de autoload em wp_options
Cada pedido WordPress carrega para memória todas as opções marcadas com autoload = yes em wp_options. Num WordPress predefinido, isto ronda os 200 KB. Numa loja WooCommerce com cinco anos de vida e uma dúzia de plugins desativados que nunca limparam os seus dados, pode chegar aos 30 MB.
Verifique com esta consulta SQL:
SELECT option_name, LENGTH(option_value)
FROM wp_options
WHERE autoload = 'yes'
ORDER BY LENGTH(option_value) DESC
LIMIT 30;
Se algum dos 30 primeiros resultados tiver mais de 100 KB e não souber por que está com autoload ativado, quase certamente não deveria estar. Culpados comuns: restos de transientes que nunca expiraram, registos de tarefas cron, caches de APIs de terceiros, dados de migração de plugins abandonados.
Mudar os piores casos para autoload = no (ou eliminá-los completamente) tipicamente poupa entre 100 a 300 ms em cada página não cacheada. É geralmente a maior melhoria de desempenho encontrada na maioria das auditorias WooCommerce.
2. O desastre das consultas em wp_postmeta
O WooCommerce armazena quase todos os dados de produtos — preço, stock, atributos, dimensões, variações — em wp_postmeta. Um produto com 12 variações e 8 atributos cria cerca de 100 linhas em wp_postmeta. Um catálogo de 500 produtos desse tipo representa 50 000 linhas. Um catálogo de 5 000 produtos representa meio milhão.
O índice padrão do WordPress em wp_postmeta incide sobre (post_id, meta_key). Cobre o padrão “devolve-me os metadados deste produto”. Não cobre o padrão típico do WooCommerce “devolve-me todos os produtos em que _price está entre X e Y”, o que força varrimentos completos à tabela.
O WooCommerce 8.2 introduziu tabelas de encomendas personalizadas (HPOS), que move os dados de encomendas para fora do wp_postmeta por completo. Ative-o. Para os dados de produtos, o alívio vem de uma das seguintes opções:
- Um índice adicional:
ALTER TABLE wp_postmeta ADD INDEX (meta_key(32), meta_value(32))— a utilizar com cautela em tabelas de grande dimensão, mas com impacto transformador nas páginas de categoria com filtros de preço - Mover as meta keys mais acedidas (
_price,_stock_status,_sku) para uma tabela plana personalizada consultada pelas páginas de categoria
3. Fragmentos do carrinho e o overhead de AJAX
O WooCommerce atualiza o mini-carrinho em cada carregamento de página através de uma chamada AJAX a ?wc-ajax=get_refreshed_fragments. Numa página em cache, isto significa: a página carrega rapidamente (a partir da cache) e de seguida dispara imediatamente um pedido AJAX sem cache que executa o arranque completo do WordPress.
Numa loja com tráfego elevado, esta única chamada gera mais trabalho PHP sem cache do que todos os outros pedidos combinados. Em servidores com poucos recursos, é a diferença entre suportar 1.000 utilizadores simultâneos e colapsar aos 200.
Duas soluções:
- Desativar os fragmentos completamente nas páginas onde o carrinho não está visível (a maioria das páginas de categoria, blog e páginas de conteúdo). Um filtro, dez linhas de código.
- Mover o contador do carrinho para o lado do cliente: ler a partir de um cookie definido ao adicionar ao carrinho e apresentar o mini-carrinho apenas nas páginas de carrinho e checkout. Reduz a chamada AJAX para praticamente zero.
4. Proliferação de plugins no carrinho e checkout
As páginas de carrinho e checkout são executadas sem cache em cada pedido. Cada plugin que se liga a woocommerce_init, woocommerce_checkout_process ou woocommerce_cart_calculate_fees paga o custo total de execução nestas páginas.
Num site WooCommerce típico com 3 anos de vida, é habitual encontrar:
- 3 plugins de carrinho abandonado (um atual, dois deixados de experiências anteriores)
- 2 integrações diferentes de rastreamento de conversões (uma configurada pelo marketing, outra pelo programador anterior)
- Um plugin de extensão de cupões que adiciona 5 consultas por cada cálculo do carrinho
- Uma calculadora de envio que contacta uma API remota em cada carregamento de página
A auditoria de plugins nestas duas páginas — o que está instalado, o que ainda está ativamente em uso, o que pode ser substituído pelo WooCommerce nativo ou por uma única linha de código do tema — reduz habitualmente o tempo de resposta do carrinho/checkout entre 30 e 50%.
5. Cache de objetos, devidamente configurada
O cache de páginas (Cloudflare, LiteSpeed, WP Rocket) ajuda as páginas que podem ser colocadas em cache. O fluxo do carrinho e do checkout precisa de um cache de objetos — Redis ou Memcached — para manter as páginas não colocáveis em cache a funcionar rapidamente.
A maioria das lojas ou não tem nenhum, ou tem-no instalado mas mal configurado: partilhado entre vários sites sem prefixação de chaves adequada, subdimensionado de modo a que o cache seja constantemente invalidado, ou com grupos específicos do WooCommerce (wc_session_id, wc_cart) que na prática não estão a ser colocados em cache.
Confirme com wp_cache_get_stats() ou inspecionando o Redis diretamente. Um cache de objetos a funcionar corretamente apresenta taxas de acerto acima dos 90% numa loja com tráfego elevado. Abaixo disso, provavelmente não está a fazer cache de nada útil.
6. Dívida de regeneração de imagens
Cada redesign altera os tamanhos de imagem que o tema solicita. As lojas WooCommerce acumulam dezenas de tamanhos intermédios por imagem de produto — 300×300 do primeiro tema, 400×400 do segundo, 600×450 com recorte de uma campanha.
Os originais estão geralmente bem. O problema são as dezenas de tamanhos obsoletos que continuam a ser servidos porque o markup ainda os referencia, ou pior, a imagem original a ser servida com 4× o tamanho apresentado porque o tamanho correto não existe.
Audite com wp media regenerate após estandardizar um conjunto de tamanhos de imagem sensato no tema. A entrega em WebP através de uma CDN de imagens (Cloudinary, Bunny, ou uma CDN com negociação automática de formato) permite-lhe reduzir o peso das imagens entre 30 a 60% sem tocar nos originais.
7. Processamento em segundo plano para o trabalho pesado
Por defeito, o WooCommerce envia os e-mails de confirmação de encomenda de forma síncrona, durante o pedido de checkout. O cliente aguarda enquanto o SMTP negoceia. Se a integração com o seu CRM/ERP também estiver ligada ao woocommerce_thankyou, o cliente aguarda por isso também. Se algo nessa cadeia expirar, a encomenda já foi criada mas o cliente vê um erro.
Mova tudo o que não é crítico para a resposta para o ActionScheduler (o sistema de filas que o WooCommerce já inclui):
- E-mails de confirmação e de administração
- Integrações com CRM, ERP e contabilidade
- Sincronização de inventário com outros canais
- Envio de dados de análise para qualquer destino que não seja o pixel de conversão
O tempo de resposta do checkout desce de 4 a 8 segundos (valor típico) para menos de 1,5 segundos (valor alcançável). E uma API de terceiros lenta deixa de conseguir comprometer todo o fluxo de checkout.
A ordem das operações
Se está perante uma loja lenta e não sabe por onde começar, esta é a ordem pela qual eu percorreria:
- Auditoria de opções com carregamento automático (1 hora, maior ganho isolado)
- Fragmentos do carrinho (1 a 2 horas, impacto imediato na velocidade percebida)
- Auditoria de plugins no carrinho e no checkout (4 a 8 horas, ganho real e mensurável)
- Cache de objetos (varia consoante a configuração do servidor)
- Processamento em segundo plano para e-mails/integrações (8 a 16 horas)
- Regeneração de imagens e CDN (trabalho paralelo, não bloqueia o resto)
- Índices de postmeta (por último, requer um ambiente de testes cuidadoso e um plano de reversão em tabelas grandes)
Em conjunto, numa loja que já auditeie, estes sete pontos reduziram consistentemente o LCP de 4-6s para menos de 2s, duplicaram o número de utilizadores simultâneos que o mesmo plano de alojamento consegue suportar, e diminuíram o abandono no checkout em alguns pontos percentuais — o que numa loja de 500 mil euros representa receita real.
Nenhum deles é misterioso. São simplesmente aspetos que não aparecem num guia genérico de “acelerar o WordPress” porque são específicos do WooCommerce.