— Journal · 6 MIN LEITURA · Engineering

Reconstruímos o nosso site a remover coisas

Duas folhas de estilo, dois pacotes, duas cópias de cada template — e um interruptor que há meses respondia sempre o mesmo. O que saiu, quanto pesava, e como provámos que nada partiu.

← All journal
Published
19 September 2026
Reading
6 minutes
Topics
Engineering
Performance
Design
Written by
Pedro Thomaz
Share
LinkedIn ↗
Reconstruímos o nosso site a remover coisas

O nosso site tinha duas de cada coisa. Duas folhas de estilo, dois pacotes de JavaScript, duas versões de cada template — uma para o site que as pessoas viam, outra para o site que já tínhamos substituído. Um interruptor num ficheiro de configuração decidia qual delas recebia, e há meses que respondia sempre o mesmo.

É um estado normal durante uma reconstrução. É um mau estado para deixar a correr, porque a versão que ninguém vê continua a custar. Cada página levava 28KB de JavaScript escrito para um layout que já não existia. Cada deploy carregava 240KB de CSS que nenhum browser chegava a interpretar. E cada alteração tinha de ser feita duas vezes — ou feita uma vez e esquecida na outra cópia.

Por isso apagámos tudo. 6865 linhas, 560KB de ficheiros, o markup de dezanove templates para um site que já tinha sido substituído. O resultado é um site que faz mais do que fazia no mês passado e pesa consideravelmente menos.

"Menos é mais" é um orçamento, não um estado de espírito

"Menos é mais" costuma ser usado como argumento de gosto — menos caixas, mais espaço em branco, tipografia mais calma. Essa parte é verdadeira, e é a parte fácil. A versão que muda mesmo a sensação de um site é a que se consegue contar: cada elemento da página tem de justificar os seus bytes, o seu tempo de parsing e o seu paint.

Uma fotografia de hero justifica-se. Uma segunda cópia da mesma fotografia, descarregada a 2400px porque ninguém escreveu um srcset, não. Um cursor desenhado à mão justifica-se se disser o que se vai clicar. Um carrossel de logótipos de clientes que ninguém percorre não — e esse cortámo-lo do desenho original antes sequer de ir para o ar.

A disciplina é a mesma que usamos em projetos de clientes: pode acrescentar-se algo bonito, desde que se saiba dizer o que custa e o que substitui.

O que saiu

A lista completa, porque afirmações vagas sobre "otimização" não valem nada:

  • A folha de estilo antiga e o pacote antigo. O main.css (240KB somando as duas cópias) e o main.js (74KB) desapareceram. O que o site atual usava mesmo daquele pacote — pesquisa, selector de língua, banner de cookies, modal de orçamento, faixa de clientes — foi recortado à letra para um único ficheiro de 11,7KB. Não reescrito. Recortado, para que nada pudesse mudar de comportamento pelo caminho.
  • Cinco ficheiros de "critical CSS" que nenhum template incluía desde a reconstrução, e um parcial de navegação móvel para uma navegação que já não existe.
  • Um diorama 3D — 45KB de JavaScript e uma textura de 167KB — que tinha sido substituído pelo hero de nevoeiro e continuava no repositório.
  • Um modal de trabalho que abria os casos de estudo numa camada por cima. Ligava-se a nomes de classes que os templates atuais nunca escrevem, o que é uma maneira educada de dizer que estava morto há meses.

O que ficou mais leve em vez de sair

O hero é uma fotografia de nevoeiro a passar pelo pinhal à saída de Leiria, desenhada em WebGL com uma camada de ruído deformado à frente. É a coisa mais cara do site, e fica, porque é o argumento: construímos coisas mais difíceis do que precisavam de ser, com cuidado.

O que não precisa é de chegar duas vezes. A página pré-carregava um JPEG de 113KB para o hero móvel e descarregava à parte uma versão de 247KB para servir de textura ao WebGL — a mesma fotografia, duas vezes, em dois tamanhos. Agora há uma imagem em três formatos: 27KB de AVIF para quem o entende, 29KB de WebP para os restantes, e o JPEG original por baixo para o que for mais antigo. Medido contra o original, o AVIF dá 41dB de PSNR, que é a forma técnica de dizer que ninguém vê a diferença.

O mesmo se aplicou ao resto da página. As imagens de largura total pediam 2000px fosse qual fosse o ecrã à frente. Passaram a ter uma escada de larguras, por isso um telemóvel descarrega uma fotografia do tamanho de um telemóvel: 461KB de imagens em móvel, contra mais de um megabyte antes.

O bug que só um browser lavado conseguia ver

Há uma descoberta que vale a pena registar, porque é o tipo de coisa que se esconde durante meses.

O nosso servidor diz aos browsers para guardarem JavaScript durante um ano, marcado como immutable. Está certo, e é seguro, porque cada tag de script leva a data de modificação do ficheiro em query string — muda o ficheiro, muda o URL, chega código novo.

Só que um dos ficheiros não era carregado por uma tag de script. Era importado por outro módulo, por um caminho simples, sem versão nenhuma. Quando o alterámos, quem já tinha visitado o site continuou a correr a cópia antiga — durante um ano, se lá ficasse tanto tempo. O sintoma era pequeno e irritante: o ecrã de carregamento, que deve aparecer uma vez por sessão, voltava a aparecer ao regressar à página principal.

A correção são três linhas: o import passa a ir por um import map que o servidor escreve com a versão lá dentro. A lição é a parte que interessa guardar — uma política de cache vale o que valer o URL mais fraco do grafo de dependências, e os imports de módulos são fáceis de esquecer.

Como soubemos que nada partiu

Apagar 6865 linhas de um site no ar só é responsável se se conseguir provar que o resultado não mudou. Por isso fizemos da maneira aborrecida: gerámos as 33 rotas antes da cirurgia, gerámo-las outra vez depois, e comparámo-las byte a byte, normalizando apenas o que é suposto mudar entre dois pedidos — o nonce anti-spam do formulário e o relógio do rodapé.

Zero diferenças, tirando o bloco de markup que queríamos mesmo remover. Depois a mesma varredura contra produção: todas as rotas, todos os códigos de estado, zero erros na consola. Essa varredura é agora um ficheiro no repositório, para que a próxima pessoa a mexer nisto a possa correr antes de prometer seja o que for.

Onde é que isto aterrou

O Lighthouse dá 100 em desempenho, acessibilidade, boas práticas e SEO em desktop, em todos os tipos de página, e 96–99 em móvel. O Largest Contentful Paint fica entre 0,4 e 0,6 segundos em desktop. Não há build step, nem bundler, nem framework: o site é PHP renderizado no servidor contra um CMS headless, publicado por FTP, com dois ficheiros minificados mantidos à mão.

Essa última parte é deliberada. O site de um estúdio é o único projeto em que se é cliente e engenheiro ao mesmo tempo, e é o sítio honesto para descobrir se as nossas opiniões sobrevivem ao contacto com um prazo. As nossas sobreviveram, quase todas. As que não sobreviveram estão agora apagadas.

A parte que não é sobre o nosso site

A maior parte dos sites que nos pedem para arranjar não está lenta por causa de uma má decisão. Está lenta por causa de quarenta decisões pequenas, cada uma defensável no dia em que foi tomada, nenhuma delas alguma vez removida: um segundo script de analytics, um tipo de letra que ninguém usa, uma biblioteca de componentes para três botões, um pipeline de imagens que dá a um telemóvel a fotografia de um desktop.

Ninguém agenda a remoção. Não é uma funcionalidade, não se demonstra bem, e é invisível para toda a gente exceto para quem está à espera que a página abra. É também, sem falhar, o trabalho de desempenho mais barato que existe — e o único que melhora o desenho ao mesmo tempo.

Se o seu site parece mais pesado do que devia, isso normalmente não é uma reescrita. É um inventário.

— Read next
— Next steps

Tell us what was only ever described.

info@amplifiedcreations.com