- Os serviços do GOV.UK devem funcionar com HTML em primeiro lugar para que os usuários consigam concluir tarefas essenciais independentemente do navegador, dispositivo ou condição de conexão, e todos os serviços do governo exigem aprimoramento progressivo
- O HTML tem tolerância a falhas porque ignora marcações desconhecidas e continua o parsing, o que aumenta a chance de manter navegação e funcionalidades básicas mesmo em navegadores antigos ou em páginas com alguns erros
- CSS e JavaScript são camadas mais frágeis: no CSS, um conjunto inteiro de regras pode ser ignorado por causa de seletores desconhecidos, e no JavaScript a execução do restante do código pode parar por sintaxe não suportada ou erros de API
- JavaScript deve ser usado para aprimorar HTML e CSS, e não para substituir a funcionalidade principal; até mesmo o preenchimento automático deve ser aplicado sobre elementos básicos como
<select>, para que o usuário consiga continuar se houver falha - Frameworks JavaScript client-side e SPAs podem gerar custo de desempenho, acessibilidade e manutenção, e não são necessários para serviços centrados no GOV.UK Design System que não tenham interfaces complexas
Princípios básicos do aprimoramento progressivo
- Serviços de qualidade devem ser criados de forma robusta, e o aprimoramento progressivo é uma abordagem que faz sites e aplicações funcionarem a partir do HTML
- Só depois de criar o comportamento básico em HTML devem ser adicionadas camadas como CSS e JavaScript
- Todos os serviços do governo devem seguir o aprimoramento progressivo, e esse princípio se mantém mesmo que parte do serviço ou um serviço de nível superior exija JavaScript
- Os benefícios do aprimoramento progressivo incluem:
- o serviço se torna mais robusto e de maior qualidade
- aumenta a chance de funcionar independentemente do navegador ou dispositivo
- a funcionalidade mais básica funciona e atende à principal necessidade do usuário
- incentiva boas práticas como marcação semântica, melhorando a acessibilidade
- facilita o uso do serviço por pessoas com limitações de dispositivo ou conexão
- Ao usar soluções COTS ou contratar fornecedores externos para entregar um serviço, vale considerar incluir aprimoramento progressivo nos requisitos da estratégia de compra
Comece pelo HTML
- Serviços governamentais devem funcionar apenas com HTML
- Exemplos de serviços que devem funcionar só com HTML:
- serviços transacionais, como formulários em que o usuário fornece informações ao governo
- serviços no formato de smart answers, como Registering a birth abroad
- sites baseados em conteúdo, como o foreign travel advice do GOV.UK
- A camada HTML é tolerante a falhas por design
- o navegador ignora marcações que não entende e continua o parsing sempre que possível
- mesmo que haja bugs no HTML ou uso de recursos presentes apenas em navegadores modernos, ainda é provável que navegadores antigos consigam carregar o serviço
- Os usuários devem conseguir navegar pelo serviço apenas com HTML
- Use marcação semântica correta e organize de forma lógica a ordem do código-fonte e a estrutura do documento
Como usar CSS
- CSS pode ser usado para estilizar o serviço de forma que ele se pareça com o GOV.UK
- A camada CSS é relativamente tolerante a falhas
- o navegador ignora declarações individuais que não entende
- ao usar propriedades disponíveis apenas em navegadores modernos, apenas aquela declaração pode ser ignorada
- Porém, ao encontrar um seletor que o navegador não entende, ele pode ignorar todo o conjunto de regras
- O CSS pode deixar de ser carregado por vários motivos
- Para que o site tenha a aparência correta mesmo sem o carregamento do JavaScript, evite técnicas como CSS-in-JS
Como usar JavaScript
- JavaScript pode ser usado para adicionar elementos interativos ao serviço
- A camada JavaScript não é tolerante a falhas
- se o navegador do usuário não suportar determinada sintaxe ou uma API chamada, ocorrerá um erro
- quando isso acontece, o restante do JavaScript deixa de ser executado
- Se o serviço for projetado sem considerar essa possibilidade, o usuário pode ficar sem conseguir utilizá-lo
- Formas de aumentar a chance de o JavaScript funcionar corretamente em vários navegadores:
- usar detecção de recursos para APIs do navegador
- incluir polyfills para recursos de navegadores modernos
- transpilar o JavaScript para uma sintaxe comum compreendida pelos navegadores de destino
- usar testes automatizados ou linters
- fazer testes manuais regulares, inclusive em dispositivos antigos ou de baixo desempenho
- Transpilação e polyfills podem aumentar bastante o tamanho do JavaScript
- é preciso considerar esses trade-offs
- como o uso dos navegadores muda com o tempo, essas decisões devem ser revisadas regularmente
- Sempre que possível, o JavaScript deve aprimorar HTML e CSS que já ofereçam a mesma funcionalidade principal
- o preenchimento automático pode ser construído como um aprimoramento de um elemento
<select>ou de outro elemento básico semelhante - mesmo se o JavaScript falhar, o usuário ainda consegue concluir a tarefa necessária
- o preenchimento automático pode ser construído como um aprimoramento de um elemento
Alternativas ao JavaScript e canais complementares
- Se parecer que um serviço só pode ser criado com JavaScript, primeiro avalie se uma solução mais simples em HTML e CSS consegue atender às necessidades do usuário
- Se quiser oferecer gráficos interativos com JavaScript, considere estas alternativas:
- exibir os dados em tabela
- permitir exportar os dados para análise em outro aplicativo
- pré-renderizar o gráfico como imagem
- Se a funcionalidade principal do serviço não puder ser oferecida sem JavaScript, deve haver uma forma de o usuário acessar o serviço por outros canais
- telefone
- atendimento presencial
Frameworks JavaScript client-side
- Se o serviço for composto principalmente por componentes do GOV.UK Design System e não tiver uma interface complexa, não há necessidade de frameworks JavaScript client-side
- Os componentes do GOV.UK Design System incluem uma forma de trazer JavaScript para o serviço sem usar framework
- Frameworks JavaScript client-side podem ajudar na criação de interfaces complexas, mas também podem introduzir vários problemas
- Problemas que podem surgir com o uso de frameworks:
- aumentam o tamanho total da base de código e empurram o processamento para o cliente, o que pode causar problemas de desempenho para usuários em redes lentas ou dispositivos pouco potentes
- criam dependência de código de terceiros fora do controle dos desenvolvedores, e mudanças no framework podem exigir alterações grandes no serviço
- se o framework perder popularidade com o tempo, pode ficar difícil encontrar pessoas com as habilidades necessárias para mantê-lo
- Se você usar um framework JavaScript, deve atender às seguintes condições:
- ser capaz de justificar com evidências qual benefício o uso de JavaScript traz ao usuário
- conhecer e mitigar os impactos negativos
- considerar se os benefícios superam os problemas potenciais
- usar o framework apenas nas partes da interface que não podem ser criadas somente com HTML e CSS
- projetar cada parte da interface como um componente separado
- Ao separar os componentes, se o carregamento do JavaScript falhar, apenas aquele componente falha e o restante da página continua carregando normalmente
- JavaScript deve ser usado apenas para aprimorar HTML e CSS, e o usuário precisa continuar conseguindo usar o serviço mesmo em caso de falha
Motivos pelos quais CSS e JavaScript podem falhar
- CSS e JavaScript podem não ser carregados ou executados por vários motivos
- erro temporário de rede
- extensões de navegador de terceiros, como bloqueadores de anúncios
- indisponibilidade de fornecedores terceiros ao usar rede de distribuição de conteúdo
- falha de resolução de DNS
- bugs causados por atualizações do navegador
- bugs em JavaScript de terceiros executado intencionalmente na mesma página
- firewalls corporativos usados por grandes instituições, como bancos ou órgãos governamentais, que bloqueiam, removem ou alteram conteúdo
- operadoras de rede móvel que alteram conteúdo para reduzir tempo de carregamento e uso de banda
- firewalls pessoais ou softwares antivírus que alteram ou bloqueiam conteúdo
- provedores de internet que inserem seu próprio código na página em conexões inseguras, e esse código entra em conflito com o código do serviço
- Alguns usuários podem desativar recursos do navegador de propósito
- O serviço deve respeitar a escolha do usuário e continuar utilizável também nesses casos
Por que evitar aplicações de página única (SPA)
- O serviço não deve ser criado como uma aplicação de página única (SPA)
- Em uma SPA, o carregamento das páginas dentro do serviço é tratado por JavaScript, e não pelo navegador
- SPAs trazem poucos benefícios e podem prejudicar a acessibilidade
- usuários de tecnologias assistivas podem não perceber que a mesma mudança de contexto ocorreu ao ir para uma nova página
- o foco pode não ser tratado corretamente durante a navegação entre páginas
- o usuário pode não conseguir navegar com os botões de voltar e avançar do navegador
- o usuário pode não conseguir se recuperar de erros, como uma queda de conexão de rede
Critérios de teste
- Se alguns componentes do serviço dependerem fortemente de JavaScript ou de um framework JavaScript, é preciso verificar se:
- funcionam em diversos navegadores e dispositivos
- funcionam junto com tecnologias assistivas
- passam por testes para garantir bom desempenho
- Sempre que possível, esses componentes devem ser validados com testes de acessibilidade para confirmar que funcionam corretamente dentro do serviço
1 comentários
Opiniões no Hacker News
“Se você usa um framework JavaScript, deveria conseguir justificar com base em evidências qual benefício o uso de JavaScript traz ao usuário” — calma lá, gente
Um bom critério é: se o app consegue funcionar como um app de desktop, com abordagem offline first, então pode ser aceitável criá-lo como uma aplicação de página única
Photopea, Google Docs/Sheets e tldraw são exemplos; nesses casos, pode ser mais ágil e melhor do que um app de navegador com várias páginas
Assim, as maiores desvantagens — navegação entre páginas e necessidade de conexão com a internet — desaparecem
Mas, se o app precisa de conexão com a internet e de várias páginas, é melhor deixar o navegador lidar com a navegação de uma forma resiliente a falhas
Se você precisa de algo como uma GUI de desktop offline ou em vários sistemas operacionais, uma aplicação de página única tem vantagem; se só quer criar um site, uma aplicação de página única talvez não seja o ideal
Uma aplicação de página única em si e a complexidade para construí-la são coisas separadas
Comecei na web quando era criança, nos anos 90. Eu nem sabia o que eram CSS ou JS, e conhecia JS só como aqueles scripts mágicos que eu copiava e colava para fazer alguma coisa piscar
Mais tarde, criei sites dinâmicos em PHP para negócios locais e, nessa época, também aprendi um pouco de JS e CSS
Depois abandonei o desenvolvimento web porque detestava gastar tanto tempo fazendo tudo funcionar em navegadores horríveis como o IE6
Fiquei quase 6 anos fora e voltei por volta de 2015, porque percebi que um servidor web seria útil para o trabalho que eu fazia
Mas fiquei chocado ao ver que o mundo tinha esquecido muita coisa que antes se sabia sobre HTML e CSS
Antigamente, criávamos vários stylesheets para um site, fazíamos primeiro funcionar sem JS e depois adicionávamos JS como uma camada de melhoria; essa abordagem foi esquecida
Vi desenvolvedores web fazendo toda a validação de formulários apenas em JS e nada no servidor, e, surpreendentemente, isso ainda é comum hoje
Não vejo muito o padrão comum em que o servidor valida e o JS apenas exibe o resultado. Parece que todo mundo ou implementa tudo em duplicidade ou não faz validação no servidor
Depois de ver isso, o que as pessoas faziam na web deixou de me impressionar. Não era mais a web que eu conhecia, eram apenas “aplicações” feitas em JS, e defender uma abordagem web first era uma batalha perdida
Comecei ainda criança com HTML 3.2/XHTML e CSS; alguns anos depois trabalhei com Django + jQuery, até me interessar por infraestrutura
Cerca de um ano atrás, trabalhei junto com uma equipe de desenvolvimento web e fui ver o que eles faziam, mas não conseguia mais entender nada
A complexidade era esmagadora, e parecia que a maior parte do tempo era gasta em gerenciamento de complexidade, como reduzir tempo de build, resolver problemas de dependências, lidar com problemas estranhos de TypeScript e tratar erros em vários componentes
Na época de Django+jQuery, o foco ainda estava no que o usuário podia ver e usar
Claro que nunca se pode confiar no cliente, então depois é preciso validar de novo no servidor
Reduzir a carga do servidor é útil
É um bom conselho, mas afirmações como “usuários de tecnologias assistivas não conseguem perceber a mesma mudança de contexto ao ir para uma nova página”, “não conseguem gerenciar o foco na navegação entre páginas”, “não conseguem navegar com os botões voltar/avançar do navegador” e “não conseguem se recuperar de erros quando a conexão de rede cai” não são, estritamente falando, falsas?
Muitas, talvez a maioria, das aplicações de página única simplesmente não se preocupa com isso, mas essas coisas podem ser implementadas em uma aplicação de página única
No momento em que você entra no território das aplicações de página única, precisa reinventar muitas rodas para voltar ao mesmo nível, ou acaba substituindo recursos nativos por alternativas em JS
Pense em formulários de várias páginas: quantas aplicações de página única guardam tudo na memória e só enviam uma única requisição no final?
Sem JS, o backend teria salvado o estado de cada etapa para que fosse possível voltar ao formulário depois ou atualizar a página sem perder nada
Se um site em HTML básico funciona bem com os padrões, por que impor esse lixo?
Se o usuário não permite mexer retrospectivamente no histórico de navegação, só resta uma opção
Criar corretamente o histórico do navegador no momento em que o histórico é usado
Gostaria que a internet inteira seguisse esse conselho
O antigo volta a ser novo
Não deveríamos priorizar a solução mais simples possível em vez do que está na moda hoje?
Só porque o restante da indústria estava embriagado de JS não significa que todo mundo estivesse
Por que Linux não está nessa lista?
https://www.gov.uk/service-manual/technology/designing-for-d...
Uma resposta um pouco mais séria, mas na mesma linha, é que existem dezenas de distribuições e, se incluirmos os forks da família Mozilla dentro delas, também há algo como uma dezena de navegadores.
Até daria para escolher uma distribuição/navegador oficial, mas a base de usuários dessa única escolha ficaria minúscula.
Até o Ubuntu parece ter cerca de 1% de participação entre sistemas operacionais desktop, segundo números que dá para inferir por métricas auxiliares.
Pergunta séria: pelos comentários, parece que as pessoas gostam dessa abordagem.
Então por que a tendência geral é usar frameworks como React e JavaScript, às vezes sem necessidade?
É leve, tem layout limpo, boa acessibilidade e, em geral, funciona com o mínimo de JavaScript ou até sem JavaScript nenhum.
Em contrapartida, não gosto da maioria das aplicações de página única. Elas quebram muitas funcionalidades esperadas do navegador, são inúteis sem JavaScript e muitas vezes carregam todo tipo de dependência pesada de vários sites de terceiros.
Mas o que os usuários gostam e o que os desenvolvedores gostam e conseguem criar rapidamente muitas vezes são coisas bem diferentes.
Quando algo passa a ser aceito como padrão da indústria, decidir seguir a corrente é seguro.
Além disso, ninguém faz developer relations para HTML/CSS/JS puro.
Quando você pesquisa como fazer alguma coisa, quase tudo que aparece é relacionado a frameworks.
Se você cria um programa que roda no seu próprio computador, precisa arcar diretamente com esse custo e, no mínimo, explicar ao financeiro por que os custos de cloud aumentaram 5%.
Mas, se você roda software no dispositivo de outras pessoas, como um desenvolvedor front-end, o custo é quase inexistente.
Os sinais negativos chegam por caminhos como relatos de usuários, tickets de suporte ou talvez posts no Twitter, e esse processo tem tanto viés de seleção que é bem provável que você não veja o quadro completo.
No fim, é tudo uma questão de incentivos.
A web está substituindo os clientes pesados tradicionais, e esses clientes também pressupunham uma conexão de rede razoavelmente estável e certas especificações de plataforma.
Sistemas governamentais precisam funcionar no menor denominador comum, mesmo que ele não seja comum.
Uma startup de tecnologia pode existir no começo com apenas 1 cliente, e, quando cresce, pode acreditar que seus requisitos acabarão se tornando relativamente comuns.
Na verdade, acho que desenvolvedores front-end não gostam dessa abordagem justamente por serem desenvolvedores front-end. Caso contrário, quase não sobraria front-end para desenvolver.
Esse também é o caminho que tento seguir. Entrego HTML com dados já buscados no servidor, faço no cliente o que pode ser feito no cliente para reduzir idas e vindas ao servidor, crio layouts responsivos com o mínimo de CSS e uso JS puro.
Se necessário, basta dividir em páginas web separadas.
Mas, para meus colegas, parece soar estranho e antiquado só porque uso apenas HTML, CSS e JS puro.
Não há nenhuma deficiência específica nisso.
O texto também diz que usar o lado do servidor de forma indiscriminada não é boa engenharia de software.
Vale notar que ele diz “pode causar problemas”, não “causa problemas”.
Frameworks JavaScript do lado do cliente podem ajudar a criar serviços com interfaces de usuário complexas, mas podem aumentar o tamanho total da codebase e empurrar o processamento para o cliente, criando problemas de desempenho para usuários em redes lentas ou dispositivos pouco potentes.
Eles podem fazer você depender de código de terceiros que os desenvolvedores não controlam e podem exigir grandes mudanças no serviço para acompanhar alterações do framework.
Se a popularidade do framework cair, também pode ficar difícil encontrar pessoas para mantê-lo.
Se você usar um framework JavaScript, deve justificar com evidências quais benefícios ele traz aos usuários, entender e mitigar os impactos negativos e avaliar se os benefícios superam os problemas potenciais.
Além disso, ele deve ser usado apenas nas partes da interface de usuário que não podem ser criadas só com HTML e CSS, e cada parte deve ser projetada como um componente separado.
Ao separar os componentes, se o carregamento do JavaScript falhar, apenas aquele componente falha, enquanto o restante da página carrega normalmente.