Otimização WordPress do Site QualifiCAD: Estudo de caso

O

Nos últimos dias eu trabalhei na otimização parcial do site QualifiCAD, o melhor site em português de tutoriais sobre AutoCAD, Revit e SketchUp. Tive a oportunidade de passar por vários desafios e de aprender bastante. A fim de preservar esse conhecimento adquirido para outras ocasiões semelhantes, além de eventualmente ajudar algum visitante, registro nesta publicação um resumo do que aconteceu.

Situação inicial

O site é bem visitado, com aproximadamente 100.000 visualizações de páginas por mês. Ele está hospedado em um servidor na DigitalOcean com a seguinte configuração:

  • 1 CPU Intel com 1 GB RAM;
  • 25 GB de memória SSD NVMe;
  • 1 TB de transferência.

Já havíamos trabalhado anteriormente na mudança do tema e da lista de plugins, optando pelo GeneratePress com um design bem leve. Contudo, não havíamos definido nenhum plugin de otimização.

E apesar do resultado medido no GTMetrix estar razoável, o servidor encontrava-se sempre no limite da memória e com picos de uso na CPU. Ao longo do dia o site tratava algumas vezes e o WordPress lançava a mensagem de erro:

Error establishing a database connection

CLOUDFLARE E UMA FALHA NO PROCESSO

Meu primeiro erro foi não ter solicitado o backup imediato do site, pois a primeira ação sugerida – a utilização do CDN da Cloudflare – quebrou o layout…

O objetivo dessa ação foi diminuir as requisições ao servidor da DigitalOcean, uma vez que os arquivos estáticos do site passaram a ser disponibilizados pelos servidores da Cloudflare. Deu certo, a taxa de transferência na DigitalOcean, que tinha vários picos de 2 MB/s, caiu para menos de 25% disso, mas não sei por que cargas d’água o layout foi afetado. Comecei então a investigação para tentar encontrar a causa raiz do problema…

Debug do Banco de Dados

Para começar, instalei três plugins:

  1. WP Debugging: ativa o modo debug do WordPress inserindo as seguintes linhas no arquivo wp-config.php:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'SCRIPT_DEBUG', true );
define( 'SAVEQUERIES', true );
  1. Query Monitor: plugin com várias ferramentas de monitoramento como verificação das queries ao banco de dados, erros de PHP, etc. Apesar do nome fazer referência à banco de dados, esse plugin tem funções que tocam vários outros aspectos de uma instalação WordPress.
  2. Debug Bar: como diz sua descrição: “Adiciona um menu de depuração à barra de administração, permite mostrar informações de depuração sobre consultas, cache e outras informações úteis”. A sua instalação é sugerida pelo WP Debugging, mas acho que ele é totalmente dispensável quando o Query Monitor está instalado.

Usando o Query Monitor, o debug log do WordPress exibiu a seguinte mensagem de erro:

Table './[nome-do-banco-de-dados]/wp_postmeta' is marked as crashed and last (automatic?) repair failed

A tabela wp_postmeta guarda todas as informações extras de posts que são geradas por plugins de custom fields, SEO, marketing, etc. Já as informações básicas são salvas na tabela wp_posts.

Reparação do Banco de Dados

Sem buscar mais informações sobre a tabela wp_postmeta, decidi utilizar o plugin Advanced Database Cleaner PRO para otimizá-la e repará-la. Contudo, mesmo depois de executar o reparo, o plugin continuava a indicar que a tabela tinha problemas.

Sem desanimar, tentei outra solução: a ferramenta de reparação nativa do WordPress. Para utilizá-la, você deve inserir a seguinte linha no arquivo wp-config.php:

define( ‘WP_ALLOW_REPAIR’, true );

Em seguida, deve acessar a página de reparação do banco de dados – https://seu-dominio.com/wp-admin/maint/repair.php. Vai aparecer a seguinte mensagem:

WP Allow Repair

Quando você clicar em reparar o banco de dados, o sistema vai analisar tabela por tabela e reparar aquelas que estiverem corrompidas.

No meu caso, infelizmente, me deparei com a seguinte mensagem de erro:

A tabela wp_postmeta não está bem. Está elatando o seguinte erro: Table is marked as crashed and last repair failed. O WordPress tentará consertar a tabela...
Erro ao corrigir a tabela wp_postmeta. Erro: Can't create new tempfile: './[nome-do-banco-de-dados]/wp_postmeta.TMD'

Pesquisando um pouco, descobri que esse erro estava sendo causado porque já havia um arquivo com o nome wp_postmeta.TMD na pasta /var/lib/mysql/nome-do-banco-de-dados/ do servidor. Pedi então para o responsável pelo servidor deletar o arquivo (que tinha 1,5 GB!) e rodar o comando myisamchk na pasta:

myisamchk -r -f wp_postmeta.MYI

E recebi mais um erro na cabeça:

myisamchk: error: 140 when opening MyISAM-table 'wp_postmeta.MYI'

Parece que para resolver isso basta rodar o comando sem a extensão MYI, mas neste ponto eu tinha recebido acesso ao MySQL Workbench (ferramenta visual de acesso à bancos de dados MySQL) e tentei resolver o problema com ele. Daria para fazer com o phpMyAdmin também, mas eu acho que na DigitalOcean não tem cPanel.

Com o MySQL Workbench eu fiz alguns pesquisas no banco e descobri que a tabela wp_postmeta tinha mais de 1 milhão de linhas! Achei razoável supor que a impossibilidade de reparação da tabela estava ligada a esse número enorme de linhas.

Analisando as meta_keys da tabela, descobri que desses mais de 1 milhão de linhas, 951.916 começavam com o prefixo vw e se referiam ao registro semanal e mensal de usuários em cada artigo do site. Por exclusão, descobri finalmente que o vilão da história era o plugin Post View Count, que registrava justamente esses dados. Deletei o plugin e voltei para o banco de dados.

Seguindo a batalha, ao tentar deletar essas linhas malditas da tabela, a conexão MySQL Workbench com o servidor estava caindo porque a query estava demorando mais do que 30 segundos. Para quem tentava acessar o site aparecia a seguinte mensagem:

Warning: mysqlirealconnect(): (HY000/2002): No such file or directory in /var/www/html/wp-includes/wp-db.php on line 1653

Mais uma pesquisa no Google mostrou que esse problema pode ser solucionado mudando o parâmetro DB_HOST no arquivo wp-config.php de localhost para 127.0.0.1 ou para o IP do seu servidor, alterando a forma de conexão do WordPress com o banco de dados. Aparentemente essa solução é mais lenta, mas no meu caso resolveu o problema, o que é mais importante.

Depois disso, consegui limpar as linhas desnecessárias da tabela de 100.000 em 100.000 e, ufa!, repará-la (ficou com aproximadamente 92.000 linhas). Felizmente, o layout voltou ao normal e eu pude passar efetivamente para a otimização do banco de dados e do site.

Otimização do Banco de Dados

Aproveitei o momento e deletei todas as tabelas relacionadas a plugins desinstalados, assim como as linhas das tabelas remanescentes com relação a esses plugins.

Como ainda apareciam algumas slow queries no Query Monitor, eu instalei o plugin Index WP MySQL For Speed, que cria indexs para as tabelas mais importantes e muda o engine do banco de dados de MyISAM para InnoDB. A mudança surtiu efeito e sobrou apenas uma slow query referente a uma falha nativa e antiga no código-fonte do WordPress.

Otimização do Cron Jobs

Focado na diminuição dos recursos do servidor, eu passei para a otimização dos cron jobs. Instalei o plugin WP-Control para deletar jobs repetidos e aumentar o intervalo de execução de outros.

Também desabilitei o WP-Cron e ativei o cron job no servidor inserindo a seguinte linha no crontab:

*/5 * * * * /usr/bin/wget -q -O - https://qualificad.com.br/wp-cron.php?doing_wp_cron >/dev/null 2>&1

Mais informações sobre essa modificação neste artigo do site WP Speed Matters e neste outro do WPJohnny.

O único processo que eu não consegui apagar de jeito nenhum foi o Action Scheduler, que ficou como resquício de uma instalação antiga do Woocommerce. Não achei solução para sua completa desativação em nenhum site. O paliativo foi instalar o plugin Action Scheduler – Disable Default Queue Runner, que remove o executor do Action Scheduler de dentro do hook action_scheduler_run_queue.

Eventos Cron do QualifiCAD

Cache e outras otimizações

Instalei e configurei o bom e velho WP Fastest Cache. E para lidar com o lazy loading das imagens enquanto não fecho com o proprietário do site um pacote para otimizar todas as imagens, instalei e configurei o plugin Flying Images.

Por fim, aumentei o limite de memória do PHP de 64 MB para 128 MB com o seguinte comando no arquivo wp-config.php:

define( 'WP_MEMORY_LIMIT', '128M' );

Resultados

No fim das contas não descobri a relação do Cloudflare com a quebra do layout, mas os resultados no servidor foram significativos:

  • CPU: redução do número de picos de uso e diminuição dos limites dos picos de 100% para 60% da capacidade;
  • Taxa de transferência: redução de mais de quatro vezes nas requisições e transferências;
  • Memória: a otimização não surtiu efeito na memória. A solução adotada foi aumentar a memória de 1 GB para 2 GB.
Otimização Wordpress do Site QualifiCAD: Estudo de caso 1
Otimização Wordpress do Site QualifiCAD: Estudo de caso 2
Otimização Wordpress do Site QualifiCAD: Estudo de caso 3

O que ainda seria possível fazer para melhorar a nota do GTMetrix?

  • Testar a combinação dos arquivos CSS;
  • Otimizar a entrega do CSS com geradores de caminho crítico do CSS;
  • Testar o preload das páginas;
  • Adiar o carregamento dos arquivos em javascript;
  • Alterar o heartbeat;

Mas vamos deixar essas tarefas para outro momento porque a demanda cresceu muito além do previsto inicialmente.

Gostou do artigo? Ficou alguma dúvida? Tem alguma sugestão ou correção a fazer? Deixe seu comentário a seguir.

Sobre o autor

Frederico B. Teixeira

Belo-horizontino morando em Brasília, católico, marido de sorte, pai de duas meninas e três meninos, engenheiro eletricista e desenvolvedor web freelancer com múltiplos interesses.

2 Comentários