A teoria versus a prática dos "sites estáticos"
(utcc.utoronto.ca)- Ao contrário da visão de que a diferença entre sites estáticos e dinâmicos ficou difusa, numa escala longa de operação os sites baseados em arquivos estáticos ainda têm características distintas
- A forma de organizar arquivos que vem desde o início da web e a eficiência de servir arquivos estáticos são razões pelas quais sites estáticos tendem a ser mais fáceis de manter por muito tempo
- Sites estáticos têm uma fronteira clara de responsabilidades entre o servidor web e o conteúdo, como um sistema de arquivos, de modo que cada lado precisa saber muito pouco sobre o outro
- Sites dinâmicos têm dificuldade para ter uma fronteira pequena e simples entre o servidor web e o código do usuário, e também é difícil padronizar essa fronteira e sua API em uma só forma
- O critério de distinção não é a quantidade de trabalho nem a frequência de mudanças, mas onde está a fronteira e com o que cada lado precisa se preocupar
O ponto de partida do debate sobre sites estáticos
- There is no such thing as a static website, de Wesley Aptekar-Cassels, defende que a diferença entre sites estáticos e dinâmicos é menor do que parece
- Sites estáticos são mais dinâmicos e complexos do que aparentam
- Criar e operar sites dinâmicos ficou mais fácil do que antes
- Embora cada argumento seja desenvolvido de forma convincente, isso não leva necessariamente à conclusão de que a diferença entre sites estáticos e dinâmicos diminuiu
A diferença criada pela durabilidade e pela fronteira de responsabilidades
- Em uma escala de tempo longa, conteúdo web baseado em arquivos estáticos mostrou alta durabilidade
- Mesmo que servidores web e hosts específicos mudem, os arquivos estáticos e a forma de colocá-los em uma árvore de diretórios continuam desde os primórdios da web
- Servir arquivos estáticos é algo comum e eficiente até em sites dinâmicos, então um site composto só por arquivos estáticos também aproveita essas mesmas vantagens
- Se você entrega apenas conteúdo estático, fica mais fácil continuar operando um site estável, e isso historicamente não se aplicou da mesma forma a sites dinâmicos
- O núcleo de um site estático é uma fronteira de responsabilidades com isolamento simples e forte
- De um lado está a complexidade de um servidor web estático, incluindo atualizações dinâmicas como renovação de certificados HTTPS
- Do outro lado estão os arquivos estáticos, e entre eles existe um sistema de arquivos ou algo semelhante a ele
- O que cada lado exige do outro é muito limitado
- Sites dinâmicos têm dificuldade para ter essa fronteira pequena e clara entre o servidor web e o código do usuário
- Também é pouco provável que isso seja padronizado em uma única fronteira e API
- Em certo sentido, a web foi projetada para servir arquivos estáticos
- Essa diferença faz com que servidores de arquivos estáticos sejam mais vantajosos para operar e migrar do que servidores web dinâmicos e ambientes de execução
- Servidores de arquivos estáticos são fáceis de encontrar
- Mesmo que o operador atual pare de manter o site, é fácil movê-lo para outro lugar
- Essa durabilidade vale ao menos para sites estáticos de pequeno e médio porte que cabem em um único servidor
- A distinção entre sites estáticos e dinâmicos não é nebulosa
- O critério não é a quantidade de trabalho para criar e operar o site, nem o volume de elementos que mudam regularmente, como a renovação de certificados HTTPS
- O critério é onde está a fronteira e com o que cada lado precisa se preocupar
- Sites estáticos têm uma fronteira nítida que permite tratar os dois lados de forma independente, enquanto sites dinâmicos não têm essa fronteira por natureza e, quando necessário, é preciso traçá-la artificialmente
1 comentários
Opiniões do Hacker News
Eu vivo de um site de conteúdo e, este ano, migrei do Craft CMS para um gerador de sites estáticos que eu mesmo criei
Agora não preciso me preocupar com servidor nem CMS, não preciso de atualizações e me livrei de um banco de dados pesado e de uma configuração de cache complexa. Hoje é apenas um servidor de arquivos estáticos, então é mais estável e quase não exige manutenção
O melhor de tudo é que consigo trabalhar offline. Só preciso de um editor de texto, então até um Macbook 12" pequeno parece muito rápido
O controle de versão também é muito útil: dá para revisar ou reverter mudanças e fazer busca/substituição com expressões regulares em todo o conteúdo. Arquivos de texto são fáceis de lidar
Escrevi aqui como foi essa transição e por que ela funciona bem: https://nicolasbouliane.com/projects/ursus
Mas seria bom se essa tecnologia se tornasse mais acessível também para quem não tem capacidade de recompilar e fazer deploy. É uma forma rápida e barata de criar sites, mas ferramentas existentes como Hugo fazem várias suposições sobre o usuário, criando uma barreira de entrada
Também li o texto com interesse. Criei a versão original do html-to-markdown que você usou na migração, e é bom ver que ele ainda é útil
É rápido, tem bem o conteúdo necessário e não tem firulas
Pessoalmente, eu gostaria que houvesse uma seção de séries de TV e filmes ambientados em Berlim, no passado e no presente, e também uma breve nota sobre o quão realisticamente retratam a Berlim real
Para mais de 95% dos sites, provavelmente bastaria manter 70% do conteúdo popular em cache na RAM e servir os 30% restantes a partir de SSDs capazes de 10.000 IOPS em leituras aleatórias
Se você não fica mexendo o tempo todo no design do site, o site e a geração do HTML deveriam acontecer na máquina local, e a geração completa deveria levar menos de 1 segundo
Mas a abordagem centrada em GitHub, controle de versão e editores de texto ainda é voltada demais para técnicos e programadores. Precisamos de algo como WordPress hospedado, ou algo mais próximo da época do Dreamweaver/Frontpage
Gosto do fato de poder mergulhar nos detalhes quando quero implementar algo específico. Por exemplo, consigo fazer com que, ao editar o artigo Favorite Git Aliases, ele seja convertido em um arquivo
.bash_aliases, enviado ao GitLab e também espelhado no GitHubPara quem tiver curiosidade, está em https://jdsalaro.com. Ainda não escrevi em detalhes sobre a stack nem os motivos, mas pretendo documentar aos poucos
Por enquanto, deixei escrito um cheatsheet de Markdown para Sphinx e Myst (https://jdsalaro.com/cheatsheet/sphinx-myst-cheat-sheet/) e um método para carregar
environment.pickle(https://jdsalaro.com/howto/sphinx-load-environment-pickle/)Isso também significa usar menos recursos como eletricidade, bastar hardware menor e, acima de tudo, melhorar a segurança. Sites estáticos são mais difíceis de atacar, e as possíveis falhas ficam restritas ao servidor web, não ao código do site
Costumo usar Hugo, que é muito rico em recursos e bem acabado. Já criei sites multilíngues com ele
Também vale considerar integrar Turbo Hotwired a sites estáticos. Isso pode aumentar a responsividade da navegação e reduzir a carga tanto no servidor quanto no cliente
Se necessário, também é possível integrar o Turbo ao Mercure para fazer streaming de páginas em tempo real
A maior diferença entre sites estáticos e dinâmicos é a superfície de ataque de segurança
No pior caso, um servidor web de site estático só pode ser induzido a servir o arquivo errado, e isso pode ser mitigado colocando no servidor apenas arquivos que já poderiam ser servidos
Sites dinâmicos podem ser induzidos a executar código, a retornar dados incorretos de bancos de dados acessíveis e também a modificar dados
Comprometimentos de WordPress acontecem o tempo todo; comprometimentos de Nginx, não
Tecnicamente, não existe site que não execute código. Do servidor web ao driver do sistema de arquivos e ao sistema operacional, tudo é código
É verdade que arquivos estáticos reduzem a superfície de ataque, mas devemos pensar a fundo no porquê e projetar sistemas dinâmicos inteligentes que tenham a segurança de sites estáticos
No fim, o ponto central é a entrada e como ela é tratada. Mesmo que você execute código extremamente complexo, se ele não recebe nenhuma entrada, não há como atacá-lo. Claro que, sem entrada, ele nem saberia qual página mostrar, então sites estáticos também têm entrada. A distinção importante está aí
Concordo que a superfície de ataque de um site estático é menor, mas acho que o motivo maior é que nginx recebe muito mais revisão e evolui mais lentamente do que a combinação média de plugins do WordPress
Se você criar seu próprio servidor web estático, a primeira versão provavelmente será mais vulnerável a ataques do que uma instalação padrão do WordPress
Um site estático, em tese, talvez nunca precise de atualização. Enquanto o alvo, como a versão do HTML, não mudar, praticamente nem existe o conceito de atualização
locationcom a diretivaaliasDo ponto de vista de um desenvolvedor, a distinção fica bem clara quando se toma como base a abstração que a Web oferece, ou seja, a hipermídia fornecida sobre HTTP/S
A semântica dessa abstração é uma estrutura em que entra uma requisição, com cabeçalhos e corpo, para um determinado caminho, e sai uma resposta, também com cabeçalhos e corpo. Detalhes intermediários de rede, como TLS, ficam ocultos
Na prática, frameworks modernos escondem ainda mais coisas do desenvolvedor, gerenciando automaticamente até sessões de autenticação e cabeçalhos de requisição. Dentro dessa abstração, a distinção padrão de que “estático não depende da requisição/estado, dinâmico depende” é clara, mas essa distinção se apoia na semântica fornecida pela abstração
Isso é parecido com o TCP operar como um protocolo orientado a conexão sobre uma infraestrutura subjacente que, fundamentalmente, é baseada em pacotes. É possível usar TCP em aplicações que precisam de transmissão de dados em fluxo ou em pacotes
Dá para argumentar que “na prática está em cima de IP, então não há distinção”, mas isso é olhar pela camada de abstração errada
Isso não quer dizer que o ponto do texto esteja errado. Desenvolvedores devem sempre ter em mente a presença de estado que existe por baixo de um “site sem estado”, e é bom entender as abstrações algumas camadas mais fundo do que se acha necessário
Sites pessoais misturam estático e dinâmico de um jeito curioso. A maior parte é estática, mas a parte do blog usa renderização dinâmica
Ao acessar uma URL do blog, ele pega um arquivo Markdown do disco, converte para HTML e insere esse HTML em um template para compor o restante da página, CSS etc.
Ainda assim, é rápido e eficiente. Na semana passada, quando um post do meu blog chegou ao 1º lugar no HN, um amigo me mandou mensagem dizendo “espero que você tenha configurado o Cloudflare”. Eu não tinha configurado, mas a média de carga de um VPS com 2 cores e 1 GB de memória não passou de 0,15
Algo como: “é quase tudo HTML, mas quando chegar nesta linha deste arquivo, execute código para fazer o parsing de um arquivo em outro formato e inserir o resultado na saída”
Em 2001, isso fazia muito sentido para criar um site estático com coisas como uma seção de comentários anexada a cada post do blog. Esse tipo de PHP era barato o bastante para que ISPs comuns muitas vezes permitissem colocá-lo em
/~userdir/e expô-lo à internet públicaCom uma arquitetura razoável que não dependa pesadamente demais de banco de dados, até um VPS pequeno consegue aguentar facilmente tráfego vindo do Hacker News
Se você for lançar um Threads, vai precisar do tipo de escalabilidade que o Facebook usa, mas para um site comum somente leitura não há nenhuma necessidade de gastar muito dinheiro
Consigo imaginar razões como inserir conteúdo dinâmico em templates ou reduzir tempo e complexidade de build, mas pode haver outros motivos em que não pensei
Do ponto de vista de alguém de fora que mexe um pouco com wasm, eu não entendia por que executar código do usuário no servidor para gerar páginas web “dinâmicas” seria melhor do que um simples servidor de arquivos
A parte dinâmica poderia rodar no navegador, e o servidor só serviria arquivos, não? A exceção é que os navegadores dos anos 90 eram péssimos para esse tipo de tarefa
Em termos de simplicidade e escalabilidade, nada supera um servidor de arquivos simples atrás de uma CDN
Também importa quantas tecnologias existem que não estraguem recursos básicos do navegador
Para constar, ao navegar por código-fonte, o GitHub ainda quebra o botão de voltar no meu ambiente em cerca de 40% das vezes. Uso Chrome no OSX, e nem sei como isso acontece
Na minha experiência, sites que geram HTML no lado do servidor parecem mais rápidos e confiáveis do que os que dependem de renderização no cliente. Abrir um booru com mais de 50 imagens por página quando o cache do navegador está vazio sempre parece mais rápido e agradável do que abrir uma página do GitHub só com texto, que já está em cache por toda parte e não é modificada há dias
Por exemplo, você pode querer armazenar conteúdo enviado por usuários em um banco de dados, pode precisar de autenticação e pode ter que oferecer busca de texto completo em um conjunto de dados de vários GB. Talvez também precise fornecer uma interface para algo que o navegador não consegue acessar ou validar entradas do usuário
Tudo isso exige código do usuário rodando no servidor. Então é preciso converter os dados no servidor para um protocolo de transporte bem definido, enviá-los ao cliente, convertê-los de volta e transformá-los em HTML
O mesmo vale no sentido inverso: para bloquear clientes personalizados maliciosos, é preciso validar entradas tanto no cliente quanto no servidor
Ou você pode simplesmente gerar HTML diretamente no servidor e encerrar o assunto. Dá muito menos trabalho e, para a maioria das aplicações, oferece praticamente a mesma experiência
Se houver segredos que precisam ser ocultados, como senhas de banco de dados, chaves de API ou chaves criptográficas, eles precisam ser tratados por código no servidor. Se todo o código roda no cliente, sempre existe a possibilidade de um invasor descobrir esses segredos
Também é mais fácil reduzir a superfície de ataque oferecendo ao cliente uma API menor e mais limitada. Se você deixar o cliente se conectar diretamente ao banco de dados, as permissões e configurações de segurança precisam estar exatamente corretas e sem falhas; mas, se o app só expõe a lista de livros ou filmes que ele manipula, é mais difícil atravessar as defesas
Muitas vezes, oferecer o carregamento inicial como um bloco de dados pronto para uso faz o site parecer mais responsivo. Mesmo que o tempo real seja o mesmo que baixar a aplicação, mostrar um indicador de carregamento e depois buscar e exibir os dados, a primeira opção parece mais rápida para o usuário
O servidor geralmente fica próximo ao banco de dados e a outros servidores necessários, então pode ser mais rápido carregar na ponta da frente o que é necessário. Chamadas de rede nesse ambiente são mais estáveis. Se você empurra todo o processamento para o lado do usuário, precisa lidar com chamadas mais lentas e instáveis
É bem provável que o servidor seja uma plataforma muito mais consistente do que o navegador do usuário. Os navegadores melhoraram, mas ainda há muitas diferenças sutis. No servidor, é possível especificar exatamente as ferramentas e versões de runtime necessárias e atualizá-las de forma mais determinística
Claro que isso nem sempre é verdade em todos os casos, e há exceções. Trabalho principalmente com aplicações front-end, mas há muito valor em aplicações bem projetadas que executam a maior parte, ou todo o trabalho, no navegador. Só que normalmente são web apps bastante complexos, ou casos em que alguma renderização no navegador já seria necessária de qualquer forma
A geração acontece uma única vez e termina muito rápido. Depois disso, do ponto de vista do usuário, os vários benefícios de uma página estática continuam valendo
O uso de recursos é várias ordens de grandeza menor, e a página fica muito mais responsiva. A experiência do usuário também é muito superior, embora nos últimos 10 anos não tenhamos nos importado muito com isso
rsync. Todas as páginas eram renderizadas dinamicamenteA vantagem era que, depois de configurar uma vez, eu literalmente não precisava mais me preocupar com o site e só escrevia no Markdown de que gostava
Era ótimo. Até a empresa de hospedagem acabar com o PHP
É por isso que gosto muito da exportação de páginas estáticas do NextJS
Você faz o build e distribui apenas
.html,.jse.cssestáticos na CDN ou no servidor web estático que quiser. Páginas e rotas individuais são pré-renderizadas durante o build, então o primeiro carregamento é muito rápido e os mecanismos de busca conseguem indexá-lasA forma como o NextJS divide o código
.jsem chunks e faz preload também contribui para uma experiência de carregamento rápida. Se precisar de recursos avançados, dá para torná-lo tão dinâmico quanto quiser conectando-o a uma REST API de sua escolhaCom plugins MDX, também é fácil criar áreas totalmente estáticas ou sites focados em conteúdo dentro do mesmo projeto
Porém, desde a chegada do app router na v13, parece que eles não estão dando atenção suficiente ao recurso de exportação estática. Recursos que existiam no page router, como shallow routing e rewrites/redirects estáticos, ficaram de fora da exportação estática
Como, ao usar exportação estática, você não precisa em nada do produto comercial da Vercel, fico preocupado que eles acabem removendo esse recurso no longo prazo
A maioria nem precisa de JavaScript, muito menos de React, JSX, middleware ou renderização do lado do servidor
É difícil imaginar manter no longo prazo algo com tantas partes móveis e dependências npm. Não quer dizer que não tenha utilidade, mas é melhor manter a simplicidade antes de entrar num projeto com 1,8 GiB de checkout Git e 828.128 linhas de código só para criar uma landing page
Veja o exemplo do Dan Abramov: https://gist.github.com/gaearon/9d6b8eddc7f5e647a054d7b33343...
Não é por causa do modelo de negócios da Vercel, mas porque esse caso de uso é menos comum considerando a proporção de uso do Next.js
Não tenho certeza do que você quer dizer com “rewrites estáticos”. Isso não é tratado por middleware?
Em algum momento nos anos 90, antes de ouvir a expressão “gerador de site estático”, eu gerei meu site com m4
Depois passei por PHP e Python, e agora voltei ao estático usando Jekyll
Sempre que possível, o modelo estático é muito melhor. Tirando certificados SSL, dá para consertar tudo no meu próprio cronograma
Compare isso com uma atualização de PHP que quebra alguma coisa: você precisa corrigir imediatamente, e o site fica fora do ar até terminar
Em um site estático, mesmo que o gerador quebre, o resultado da falha simplesmente permanece em estado estático. Se você não precisa publicar um post novo, não há problema
Mesmo que o servidor exploda, é só pedir a um amigo para hospedar alguns arquivos. Não é preciso perguntar “você está rodando com PHP versão X e configuração Y, né? também tem postgres?”
Alguns amigos podem dizer “não quero instalar PHP no meu computador”
Em termos de complexidade, parece só um nível acima de
sed "s/VERSION/1.2.3/g". Se dá para lidar com tudo por comandos de shell externos, não é preciso instalar algo como PythonHá alguns anos venho explorando um padrão de arquitetura que oferece tanto as vantagens do estático quanto do dinâmico
É uma abordagem que permite executar código dinâmico do lado do servidor, mas com custo de escalabilidade muito baixo e que se recupera sozinha quando algo quebra
Chamo isso de padrão Baked Data: https://simonwillison.net/2021/Jul/28/baked-data/
A ideia central é distribuir uma cópia completa, somente leitura, dos dados do site como um recurso empacotado com a aplicação
Assim como em um site totalmente estático, é preciso reimplantar o site inteiro sempre que há uma mudança, então não serve para sites que estão sendo atualizados continuamente
A vantagem é que dá para implantar em hospedagens dinâmicas baratas com scale-to-zero, como a Vercel, subir várias cópias do app para lidar com qualquer tráfego, e, se o app morrer, o host pode reiniciá-lo automaticamente
Já vi sites estáticos com busca do lado do servidor ou sistema de comentários, em que cada post ou comentário era enviado como um arquivo flat separado e, a partir daí, as páginas estáticas eram regeneradas automaticamente
Imagino que a diferença seja armazenar em sqlite em vez de arquivos Markdown e construir a partir daí. Em comparação com um site estático com funcionalidades comuns de backend/do lado do servidor, essa parece ser a única diferença significativa que salta aos olhos
Não era raro executáveis binários compilados incluírem recursos binários codificados, como arquivos ou imagens. Não se colocava muita coisa, porque isso aumentava o tamanho do executável
Exemplos em C ou C++: https://github.com/graphitemaster/incbin
O interessante é que os programas eram feitos para que os dados dentro do executável não mudassem. O código compilado roda na máquina, e isso também faz sentido do ponto de vista de segurança
Mas, se pensarmos em contêineres, por exemplo Docker, um contêiner em execução se parece com um executável empacotado, só que também tem um sistema de arquivos
Colocar dados no contêiner é um conceito parecido com recursos embutidos em um executável; a diferença é que esses dados podem mudar
Só que, mesmo que os dados mudem em tempo de execução dentro do contêiner, eles não persistem se você não anexar um armazenamento persistente
Ultimamente tenho me perguntado por que não criamos algo como um único arquivo em que “o executável e um espaço de dados volátil estão dentro do executável”. O programa e dados como um banco de dados poderiam ser combinados em um só arquivo
É uma ideia um pouco relacionada a “Baked Data”. Embutir recursos em um executável, no fim das contas, é colocar dados codificados dentro do executável
Em linguagens de script, dá para criar um arquivo de script com dados codificados em base64 diretamente em uma variável
As duas abordagens finais só são adequadas para dados estáticos relativamente pequenos, mas seria interessante criar alguma tecnologia que, de algum modo, removesse essas limitações dos executáveis
Também hospedo minha página de projetos assim: https://usmanity.com/projects
Como não quero editar arquivos HTML manualmente toda vez que adiciono um novo projeto à lista ou altero detalhes de um item existente, uso o Notion e gravo os dados antes de fazer commit no GitHub
Ao ativá-lo, ele assava todas as páginas do site como HTML em um diretório e alterava o
.htaccesspara enviar todo o tráfego para lá. Quando o conteúdo era atualizado, tudo era assado de novohttps://www.drupal.org/project/boost
Acho que uma parte que ainda faz bastante falta em sites estáticos é onde hospedar o CMS de edição
Corrijam-me se eu estiver errado, mas o Decap CMS (antes Netlify CMS) roda no navegador, lê/modifica via GitHub e depois consegue disparar rebuild e deploy. Porém, por causa de CORS, acredito que o navegador não consiga se comunicar diretamente com a API do GitHub, então ainda é necessário um pequeno servidor ou proxy
A Netlify hospeda um backend do GitHub que faz proxy das requisições, mas aí você fica preso à Netlify e às mudanças na política de preços dela
GitLab e BitBucket devem ter o mesmo problema: https://github.com/isomorphic-git/isomorphic-git#cors-suppor...
Existe algum jeito simples de resolver isso com configuração mínima? Uma extensão de navegador poderia relaxar seletivamente o CORS, mas não seria o ideal
Um CMS acoplado a um gerador de sites estáticos baseado em Git, com edição em Markdown e pré-visualização em tempo real, que rode no navegador e tenha poucas restrições de hospedagem/servidor, pareceria adequado para inúmeros sites pequenos e blogs
O gerador estático poderia ler esses dados por algo como um feed JSON para criar páginas. Por exemplo, cada registro de produto poderia incluir uma descrição em formato HTML no corpo
Assim, mesmo que outra pessoa atualize as informações dos produtos, o site continuaria estático. Achei que o Airtable seria adequado, mas, surpreendentemente, ele não oferecia bom suporte a campos HTML
Basta criar o site do jeito que você quiser, conectar o Surreal via FTP e deixar usuários ou clientes editarem apenas as partes permitidas
US$ 12 por mês é bem barato pelo valor de não precisar se preocupar com isso, e dá para oferecer um editor WYSIWYG completo a usuários não técnicos
[1] https://www.surrealcms.com
Atualmente, essa extensão funciona no VS Code instalado localmente em um notebook, mas não funciona no GitHub Codespaces
Se der para fazê-la funcionar dentro do limite gratuito do GitHub Codespaces, com um limite razoável de horas de uso, acho que seria uma solução vencedora. Você teria uma configuração totalmente online e versionada, sem precisar instalar o ambiente de desenvolvimento no seu computador; o site estático seria servido de algum lugar como S3; e ainda assim teria uma experiência completa de CMS
Um ponto muito importante dos sites estáticos é que é muito mais fácil colocar no ar e esquecer
Se você colocar em algo como um site em bucket S3, quase não precisa se preocupar
Se fizer um site “coloque no ar e esqueça” em PHP ou, pior, em WordPress auto-hospedado, ele pode ficar cheio de anúncios de pornografia russa enquanto você passa alguns meses sem verificar
Tenho alguns sites estáticos rodando, e é muito bom saber que estão sempre no ar e não precisam de conserto. Já sites dinâmicos precisam de alertas para avisar se caíram