O conceito, em uma página só
Muitas páginas pequenas
O que é a ideia, o que ela dá de graça, o que cobra em troca — e o que acontece no dia em que você resolve mudar o layout de tudo.
A ideia é de Jim Nielsen, em Lots of Little HTML Pages, e cabe numa frase: construir uma interação dentro da página, com aprimoramento progressivo, quase sempre dá mais trabalho do que escrever duas páginas HTML e ligá-las por um link.
Não é uma proibição de JavaScript. É a constatação de que boa parte do que a gente escreve em script é reimplementação do que o navegador já faz — e faz melhor, porque faz há trinta anos.
O que muda na prática
Um filtro deixa de ser um atributo data- lido por um script e vira /etiqueta/texto/. Uma ordenação deixa de ser um select que reordena o DOM e vira /ordem/nome/. O menu deixa de ser uma gaveta com aria-expanded e vira /menu/. Cada estado que você guardaria em memória vira um arquivo no disco.
| Interação de costume | Aqui |
|---|---|
| Menu que desliza por cima da página | /menu/ |
| Campo de busca que filtra ao digitar | /indice/ |
| Botões de filtro por categoria | /etiqueta/texto/ |
| Botões de filtro por raridade | /raridade/esquecido/ |
| Seletor de ordenação | /ordem/nome/ |
| Dois filtros somados ao mesmo tempo | /etiqueta/formularios/raridade/esquecido/ |
| Resultado de busca preso na tela | /busca/?q=teclado |
| Modal com a ficha do item | /especime/details/ |
Quem paga por essa multiplicação é o gerador de sítio estático. Ele é a peça que torna a ideia viável: escrever 414 páginas à mão seria insano, mandar um programa escrevê-las é trabalho de algumas dezenas de linhas.
O que o navegador dá de graça
- Endereço para tudo
- Cada estado pode ser compartilhado, favoritado, aberto em nova aba e mandado por mensagem. Um filtro aplicado vira um link que outra pessoa consegue abrir e ver exatamente a mesma coisa.
- Histórico e botão de voltar
- Sem
history.pushState, sem ouvirpopstate, sem aquele defeito clássico em que voltar não desfaz o filtro. - Foco, teclado e leitura de tela
- Ao trocar de documento, o navegador reinicia o foco e anuncia a página nova. Reproduzir isso à mão, dentro de uma página só, é uma das partes mais difíceis — e mais esquecidas — de qualquer interface feita em script.
- Estados impossíveis deixam de existir
- Não há estado em memória para dessincronizar. Se alguma coisa parecer errada, recarregar resolve, porque a página é o estado.
- A falha vem em pedaços pequenos
- Se o CSS não chegar, o documento continua legível. Se uma página quebrar, as outras continuam de pé. Não existe um pacote cuja falha derrube o site inteiro.
- Rápido a partir do segundo clique
- A folha de estilo é a mesma em todas as páginas e já está no cache. O que trafega depois disso são poucos kilobytes de HTML — menos, quase sempre, que o JSON que uma aplicação de página única buscaria para o mesmo efeito.
- Testável com curl
- Cada estado é uma URL. Verificar se um filtro funciona é pedir a página e olhar o que voltou; não é preciso simular cliques num navegador de mentira.
O que você paga em troca
- Todo clique é uma viagem de rede
- Numa conexão ruim, a diferença entre filtrar em memória e pedir outro documento aparece. Dá para amenizar com HTML pequeno e pré-carregamento, mas o custo existe e não some.
- Estado não sobrevive à navegação
- Um formulário meio preenchido, um áudio tocando, uma conversa aberta, um rascunho não salvo: nada disso atravessa a troca de documento. Este é o limite duro da ideia, não um detalhe de implementação.
- Filtros combináveis explodem
- Uma faceta com oito valores dá oito páginas. Duas cruzadas dariam vinte e quatro — só que oito dessas combinações não têm nenhum espécime, e o gerador escreve apenas as dezesseis que existem, porque é o banco que diz quais são. Três facetas já dariam quinhentas e doze, e aí podar não salva. Enquanto der para pré-calcular só o que tem resultado, a conta fecha; quando não der, é servidor.
- Nada de conteúdo por pessoa
- Página estática é a mesma para todo mundo. Personalização exige servidor, e aí a conversa passa a ser outra.
- Cabeçalho e rodapé repetidos em cada arquivo
- São alguns kilobytes multiplicados por dezenas de páginas. A compressão come quase toda a repetição, mas o custo de armazenamento e de publicação é real.
- Passa a existir uma etapa de build
- Editar um texto não é mais só editar um arquivo: é editar e regerar. Em troca, o que vai ao ar não tem nenhuma dependência em execução.
E se o layout for trocado
Essa é a primeira pergunta de quase todo mundo diante de 414 arquivos HTML: e no dia em que eu quiser mudar o desenho de tudo? A resposta depende de onde a mudança mora — e, na maioria das vezes, ela mora no lugar barato.
- Mudou o CSS
- Cor, tipografia, espaçamento, grade, modo escuro, comportamento em tela estreita: tudo isso vive em um arquivo só, de 34 kB, servido a todas as páginas. Nenhuma página é regerada e nada é republicado além dele. Essa é a maioria das mudanças de layout.
- Trocou o layout inteiro
- Este site tem 3 — clássico, disruptivo e gamer — sobre a mesma estrutura. Cada um é um arquivo de tokens: cor, tipografia, espessura de borda, curvatura, sombra, caixa alta, e cabe em poucos kilobytes. A estrutura comum também aceita ser sobrescrita, para o dia em que um layout precisar mexer na grade e não só na pele — só que aí o arquivo do tema custa o triplo. O seletor no alto da página não é um interruptor com estado: são links para a mesma página em outro endereço. E o custo aparece na conta, honestamente: as 414 páginas deste site são 138 × 3 temas — a explosão combinatória descrita ali em cima, acontecendo aqui.
- Mudou a estrutura do HTML
- Uma classe nova, um bloco a mais no cabeçalho, uma coluna extra no fichário: aí é preciso rodar o gerador outra vez. Ele reescreve as 414 páginas em milissegundos. O custo é linear e quem paga é a máquina, não você.
- Mudou o cache
- Uma alteração de HTML invalida todas as páginas na CDN; uma de CSS invalida um arquivo. Por isso vale versionar o nome da folha de estilo —
estilo.a3f19c.css— e publicar por diferença, comparando somas de verificação em vez de mandar tudo de novo. - Mudou a escala
- 414 páginas levam milissegundos. Cinquenta mil levam minutos, e aí entram build incremental, cache de artefatos e geração sob demanda. O ponto de virada costuma ser quando o build passa de um minuto: até lá, regerar tudo é mais simples do que qualquer estratégia esperta.
O risco de verdade não é o tempo de build: é uma mudança quebrar uma página que ninguém abriu. A defesa é ter poucos modelos compartilhados por muitas páginas — aqui são oito — e uma verificação que percorra o site inteiro a cada build. A deste projeto confere se todo HTML fecha direito e se as 8382 ligações internas levam a algum lugar. Leva menos de um segundo.
Onde a régua vira
- Navegação e menupágina
- Filtrar por uma facetapágina
- Ordenar uma listapágina
- Abrir a ficha de um itempágina
- Procurar um termo exatopágina + Ctrl+F
- Validar campos de um formuláriopágina
- Cruzar duas facetaspágina, só as que existem
- Busca com ranqueamentopágina, mas com servidor
- Recalcular ao arrastar um controlepágina + script
- Cruzar três ou mais facetasservidor ou script
- Mapa, canvas, edição a quatro mãosscript
uma página resolveprecisa de script
Não é uma disputa entre páginas e script. É uma régua, e a maior parte das interações de um site de conteúdo cai bem à esquerda dela — mais à esquerda do que a gente costuma admitir na hora de começar o projeto.
O que ainda faltou dizer
- Transições entre documentos
- A regra
@view-transition { navigation: auto }tirou a última desculpa para manter tudo numa página só: a animação entre estados agora é do navegador. Onde não há suporte, a navegação simplesmente acontece sem animação, e ninguém fica sem o conteúdo. - Regras de especulação
- Um
<script type="speculationrules">com JSON declarativo manda o navegador pré-carregar as páginas prováveis, o que apaga boa parte da latência de clique. É a única tagscriptque costuma valer a pena aqui — e ela não executa código seu. - Aprimoramento progressivo continua valendo
- A ideia não é abolir JavaScript, é mudar a ordem: primeiro a página existe e funciona, depois o script torna alguma coisa mais agradável. O que quebra quando o script não chega é o enfeite, não o conteúdo.
- Isto é velho, e tudo bem
- É como a web funcionava antes de 2010, com duas diferenças que mudam o veredito: geradores estáticos ficaram triviais de escrever, e o navegador ganhou transições entre documentos.
Este site, em números
- Páginas HTML
- 414
- HTML somado
- 2486 kB
- Maior página
- 21 kB
- Folha de estilo
- 34 kB
- Ligações internas
- 8382
- Temas
- 3
- JavaScript
- 0 byte
São 30 espécimes catalogados em 414 páginas. Para ver a mesma ideia do lado de dentro, o sobre conta como este site é montado, e o índice mostra tudo o que existe aqui em um documento só.