- Los servicios de GOV.UK deben funcionar con HTML primero para que los usuarios puedan completar tareas esenciales aunque cambien el navegador, el dispositivo o el estado de la conexión, y todos los servicios gubernamentales requieren mejora progresiva
- HTML tiene tolerancia a fallos porque ignora el marcado que no reconoce y sigue procesándolo, por lo que es más probable que mantenga la navegación y la funcionalidad básicas incluso en navegadores antiguos o en páginas con algunos errores
- CSS y JavaScript son capas más frágiles: CSS puede hacer que se ignore un conjunto completo de reglas cuando encuentra selectores desconocidos, y JavaScript puede detener la ejecución del resto del código por sintaxis no compatible o errores de API
- JavaScript debe usarse para mejorar HTML y CSS, no para reemplazar la funcionalidad esencial, y hasta el autocompletado debería montarse sobre elementos base como
<select>para que, si falla, el usuario pueda seguir avanzando - Los frameworks de JavaScript del lado del cliente y las SPA pueden generar cargas de rendimiento, accesibilidad y mantenimiento, por lo que no son necesarios para servicios centrados en el GOV.UK Design System que no tengan una UI compleja
Principios básicos de la mejora progresiva
- Un servicio de calidad debe construirse de forma robusta, y la mejora progresiva es un enfoque para hacer que sitios web y aplicaciones funcionen empezando por HTML
- Solo después de crear el comportamiento base con HTML se agregan capas como CSS y JavaScript
- Todos los servicios gubernamentales deben seguir la mejora progresiva, y este principio se mantiene aunque alguna parte del servicio o un servicio superior requiera JavaScript
- Los beneficios de la mejora progresiva son los siguientes
- El servicio se vuelve más robusto y de mayor calidad
- Es más probable que funcione sin importar el navegador o el dispositivo
- La funcionalidad más básica funciona y satisface la necesidad principal del usuario
- Se mejora la accesibilidad al fomentar buenas prácticas como el marcado semántico
- Facilita el uso del servicio para personas con limitaciones de dispositivo o conexión
- Al usar soluciones COTS o al encargar un servicio a proveedores externos, conviene considerar cómo incluir la mejora progresiva dentro de los requisitos de la estrategia de compra
Empezar por HTML
- Los servicios gubernamentales deben funcionar solo con HTML
- Algunos ejemplos de servicios que deben funcionar solo con HTML son los siguientes
- Servicios transaccionales, como formularios en los que el usuario entrega información al gobierno
- Servicios tipo smart answers, por ejemplo Registering a birth abroad
- Sitios web basados en contenido, como foreign travel advice de GOV.UK
- La capa HTML tiene tolerancia a fallos por diseño
- Los navegadores ignoran el marcado que no entienden y siguen procesándolo tanto como pueden
- Incluso si hay bugs en el HTML o se usan funciones disponibles solo en navegadores modernos, es probable que los navegadores antiguos puedan cargar el servicio
- El usuario debe poder navegar por el servicio solo con HTML
- Debe usarse el marcado semántico correcto, y el orden del código fuente y el esquema del documento deben organizarse de forma lógica
Cómo usar CSS
- CSS puede usarse para dar estilo al servicio de modo que se vea como GOV.UK
- La capa CSS es relativamente tolerante a fallos
- Los navegadores ignoran declaraciones individuales que no entienden
- Si se usa una propiedad disponible solo en navegadores modernos, puede ignorarse solo esa declaración
- Sin embargo, si el navegador encuentra un selector que no entiende, puede ignorar el conjunto completo de reglas
- CSS puede no cargarse por varias razones
- Para que el sitio se vea correctamente aunque JavaScript no cargue, conviene evitar técnicas como CSS-in-JS
Cómo usar JavaScript
- JavaScript puede usarse para agregar elementos interactivos al servicio
- La capa de JavaScript no es tolerante a fallos
- Si se usa sintaxis que el navegador del usuario no soporta o se llama a una API no compatible, se produce un error
- Si ocurre un error, el resto de JavaScript no se ejecuta
- Si el servicio se diseña sin tener en cuenta esa posibilidad, puede ocurrir que el usuario no pueda usarlo
- Algunas formas de aumentar la probabilidad de que JavaScript funcione correctamente en varios navegadores son las siguientes
- Usar detección de características para las API del navegador
- Incluir polyfills para funciones de navegadores modernos
- Transpilar JavaScript a una sintaxis común que los navegadores objetivo puedan entender
- Usar pruebas automatizadas o linters
- Hacer pruebas manuales periódicas, incluso en dispositivos antiguos o de bajo rendimiento
- El transpiling y los polyfills pueden aumentar mucho el tamaño de JavaScript
- Hay que considerar esas compensaciones
- Como el uso de navegadores cambia, las decisiones deben revisarse periódicamente
- Siempre que sea posible, JavaScript debe mejorar HTML y CSS que ya proporcionen la misma funcionalidad esencial
- El autocompletado puede construirse como una mejora sobre un elemento
<select>o un elemento base similar - Aunque JavaScript falle, el usuario debe poder seguir completando la tarea necesaria
- El autocompletado puede construirse como una mejora sobre un elemento
Alternativas a JavaScript y canales complementarios
- Si se considera que un servicio solo puede construirse con JavaScript, primero debe revisarse si una solución más simple hecha con HTML y CSS puede satisfacer la necesidad del usuario
- Si se quiere ofrecer un gráfico interactivo con JavaScript, pueden considerarse estas alternativas
- Mostrar los datos en una tabla
- Permitir exportar los datos para analizarlos en otra aplicación
- Prerenderizar el gráfico como una imagen
- Si la funcionalidad esencial del servicio no puede ofrecerse sin JavaScript, debe habilitarse otra manera para que el usuario use el servicio por otros canales
- Teléfono
- Visita a una oficina
Frameworks de JavaScript del lado del cliente
- Si el servicio está compuesto en su mayor parte por componentes de GOV.UK Design System y no tiene una UI compleja, no hace falta un framework de JavaScript del lado del cliente
- Los componentes de GOV.UK Design System incluyen una forma de incorporar JavaScript al servicio sin usar un framework
- Los frameworks de JavaScript del lado del cliente pueden ayudar a crear UI complejas, pero también pueden introducir varios problemas
- Entre los problemas que puede traer el uso de frameworks están los siguientes
- Aumentan el tamaño total de la base de código y empujan el procesamiento al cliente, lo que puede causar problemas de rendimiento para personas con redes lentas o dispositivos de bajo rendimiento
- Hacen que se dependa de código de terceros que los desarrolladores no controlan, por lo que adaptarse a cambios del framework puede requerir cambios importantes en el servicio
- Si con el tiempo el framework pierde popularidad, puede resultar difícil encontrar personas con las habilidades necesarias para mantenerlo
- Si se usa un framework de JavaScript, deben cumplirse las siguientes condiciones
- Debe poder justificarse con evidencia qué beneficio aporta JavaScript a los usuarios
- Deben conocerse y poder mitigarse los impactos negativos
- Debe considerarse si los beneficios superan los problemas potenciales
- El framework debe usarse solo en partes de la UI que no puedan construirse solo con HTML y CSS
- Cada parte de la UI debe diseñarse como un componente separado
- Si se separan los componentes, cuando falle la carga de JavaScript solo fallará ese componente individual y el resto de la página seguirá cargando normalmente
- JavaScript debe usarse solo para mejorar HTML y CSS, y aunque falle, el usuario debe poder seguir usando el servicio
Por qué pueden fallar CSS y JavaScript
- CSS y JavaScript pueden no cargarse o no ejecutarse por varias razones
- Errores temporales de red
- Extensiones de navegador de terceros, como bloqueadores de anuncios
- Caídas de proveedores externos cuando se usa una red de distribución de contenido
- Fallas en la resolución de DNS
- Bugs generados por actualizaciones del navegador
- Bugs en JavaScript de terceros que se ejecuta intencionalmente en la misma página
- Firewalls corporativos usados por grandes instituciones, como bancos o ministerios, que bloquean, eliminan o modifican contenido
- Operadores de red móvil que modifican contenido para reducir tiempos de carga y uso de ancho de banda
- Firewalls personales o software antivirus que modifican o bloquean contenido
- Proveedores de internet que insertan su propio código en la página en conexiones no seguras, y ese código entra en conflicto con el código del servicio
- Algunas personas pueden desactivar funciones del navegador de forma intencional
- El servicio debe respetar la elección del usuario y permitir que esas personas sigan utilizándolo
Por qué debe evitarse una aplicación de página única (SPA)
- No debe construirse el servicio como una aplicación de página única (SPA)
- Una SPA es una forma en la que JavaScript, y no el navegador, maneja la carga de páginas dentro del servicio
- Las SPA aportan muy pocos beneficios y pueden perjudicar la accesibilidad
- Las personas que usan tecnologías de asistencia pueden no darse cuenta de que ocurrió el mismo cambio de contexto que sucede al ir a una nueva página
- Puede que no se gestione correctamente el foco al cambiar de página
- Puede que el usuario no pueda navegar con los botones atrás y adelante del navegador
- Puede que el usuario no pueda recuperarse de errores, como una interrupción en la conexión de red
Criterios de prueba
- Si algunos componentes del servicio dependen mucho de JavaScript o de un framework de JavaScript, debe comprobarse lo siguiente
- Que funcionen en distintos navegadores y dispositivos
- Que funcionen junto con tecnologías de asistencia
- Que pasen pruebas para garantizar un buen rendimiento
- Siempre que sea posible, debe verificarse con pruebas de accesibilidad que esos componentes funcionen correctamente dentro del servicio
1 comentarios
Opiniones en Hacker News
“Si usas un framework de JavaScript, deberías poder justificar con fundamentos qué beneficio aporta el uso de JavaScript al usuario”. Bueno, calmémonos un poco
Un buen criterio es que, si la app puede funcionar como una app de escritorio, con enfoque offline-first, entonces está bien hacerla como una aplicación de una sola página
Photopea, Google Docs/Sheets y tldraw son ejemplos; en esos casos puede sentirse más ágil y ser mejor que una app de navegador de varias páginas
Así desaparecen sus mayores desventajas: el cambio entre páginas y la necesidad de conexión a internet
Pero si la app necesita conexión a internet y varias páginas, es mejor dejar que el navegador maneje la navegación de una forma resistente a fallas
Si necesitas algo tipo GUI de escritorio sin conexión o en varios sistemas operativos, una aplicación de una sola página tiene ventaja; si solo quieres crear un sitio web, quizá una aplicación de una sola página no sea lo óptimo
Una cosa es la aplicación de una sola página en sí, y otra la complejidad necesaria para construirla
Empecé en la web de niño, en los 90. No sabía qué eran CSS ni JS, y de JS solo entendía que era copiar y pegar scripts mágicos para hacer parpadear algo
Más adelante hice sitios dinámicos en PHP para negocios locales, y ahí aprendí algo de JS y CSS
Luego dejé el desarrollo web porque odiaba pasar tanto tiempo haciendo que funcionara en navegadores terribles como IE6
Estuve casi 6 años fuera y volví alrededor de 2015, porque me di cuenta de que un servidor web sería útil para lo que estaba haciendo
Pero me impactó ver que el mundo había olvidado muchas de las cosas que antes se sabían sobre HTML y CSS
Antes hacíamos varios stylesheets para un sitio, primero lo hacíamos funcionar sin JS y después agregábamos JS como una mejora progresiva; esa forma se olvidó
Vi a desarrolladores web hacer toda la validación de formularios solo en JS y nada en el servidor, y sorprendentemente eso sigue siendo común
No veo mucho el patrón habitual de que el servidor valide y JS solo muestre los resultados. Parece que todos duplican la implementación o directamente no validan en el servidor
Después de ver eso, lo que la gente hacía en la web ya no me impresionaba. No era la web que conocía, sino “aplicaciones” hechas con JS, y defender el enfoque web-first era una batalla perdida
De chico empecé con HTML 3.2/XHTML y CSS; unos años después trabajé con Django + jQuery y luego me atrajo más la infraestructura
Hace más o menos un año trabajé con un equipo de desarrollo web y miré lo que hacían, pero ya no entendía nada
La complejidad era abrumadora, y parecía que pasaban la mayor parte del tiempo en gestionar complejidad: reducir tiempos de build, resolver problemas de dependencias, lidiar con problemas raros de TypeScript y manejar errores en múltiples componentes
En la época de Django+jQuery todavía el foco estaba en lo que el usuario podía ver y usar
Claro que nunca se puede confiar en el cliente, así que después hay que volver a validar en el servidor
Reducir carga del servidor es útil
Es un buen consejo, pero ¿no es estrictamente falso decir que “los usuarios de tecnologías de asistencia no pueden percibir el mismo cambio de contexto al ir a una página nueva”, “no se puede manejar el foco al cambiar de página”, “no se puede navegar con los botones atrás/adelante del navegador” o “si se cae la conexión de red no se puede recuperar de un error”?
Muchas, quizá la mayoría de las aplicaciones de una sola página simplemente no se preocupan por eso, pero esas cosas sí se pueden implementar también en una aplicación de una sola página
En cuanto entras al terreno de las aplicaciones de una sola página, tienes que reinventar muchas ruedas para volver a un nivel equivalente, o reemplazar funcionalidades nativas por sustitutos en JS
Piensa en un formulario de varias páginas: ¿cuántas aplicaciones de una sola página guardan todo en memoria y recién al final envían una sola solicitud?
Si no hubiera JS, el backend guardaría el estado de cada paso para que no se perdiera al volver al formulario más tarde o al recargar
Si un sitio web HTML básico funciona bien con los valores por defecto, ¿por qué obligarnos a esa basura?
Si el usuario no permite modificar el historial de navegación a posteriori, solo queda una opción
Crear correctamente el historial del navegador en el momento en que se usa el historial
Ojalá todo internet siguiera este consejo
Lo viejo vuelve a ser nuevo
¿No deberíamos priorizar la solución más simple posible antes que lo que esté de moda hoy?
Que el resto de la industria estuviera intoxicada con JS no significa que todos lo estuvieran
¿Por qué Linux no está en esta lista?
https://www.gov.uk/service-manual/technology/designing-for-d...
Una respuesta un poco más seria, pero en la misma línea, es que hay decenas de distribuciones y, si se incluyen los forks de la familia Mozilla dentro de ellas, también hay como diez navegadores.
Se podría elegir una distribución/navegador oficial, pero la base de usuarios de esa única opción sería extremadamente pequeña.
Incluso Ubuntu parece tener alrededor de un 1% de cuota en sistemas operativos de escritorio, según cifras que pueden derivarse de métricas secundarias.
Es una pregunta seria, pero al ver los comentarios parece que a la gente le gusta este enfoque.
Entonces, ¿por qué la tendencia general va hacia el uso de frameworks como React y de JavaScript, a veces de forma innecesaria?
Son ligeras, tienen un layout limpio, son accesibles y, en general, usan JavaScript al mínimo o incluso funcionan sin él.
En cambio, no me gustan la mayoría de las aplicaciones de una sola página. Rompen muchas funciones esperadas del navegador, son inútiles sin JavaScript y a menudo cargan todo tipo de dependencias pesadas desde varios sitios de terceros.
Pero lo que les gusta a los usuarios y lo que les gusta a los desarrolladores, y pueden construir rápido, suelen ser cosas muy distintas.
Cuando algo se acepta como estándar de la industria, la decisión de seguir la corriente es segura.
Además, nadie hace relaciones con desarrolladores para HTML/CSS/JS puro.
Si buscas cómo hacer algo, casi todo lo que aparece está relacionado con frameworks.
Si creas un programa que corre en tu propia computadora, tienes que pagar ese costo directamente y, como mínimo, explicarle a finanzas por qué el costo de la nube aumentó 5%.
Pero si, como desarrollador frontend, ejecutas software en los dispositivos de otras personas, casi no hay costo.
Las señales negativas tienen que llegar a través de reportes de usuarios, tickets de soporte o quizá publicaciones en Twitter, y ese proceso tiene mucho sesgo de selección, así que es probable que no veas el panorama completo.
Al final, todo es cuestión de incentivos.
La web está reemplazando a los clientes pesados tradicionales, y esos clientes también asumían una conexión de red bastante estable y ciertas especificaciones de plataforma.
Los sistemas gubernamentales, aunque no sean comunes, deben funcionar sobre el mínimo común denominador.
Una startup tecnológica puede existir al principio con un solo cliente y, cuando crece, puede creer que sus requisitos se volverán bastante comunes.
De hecho, creo que a los desarrolladores frontend les disgusta este enfoque precisamente porque, si no, casi no quedaría frontend por desarrollar.
Esta es también la forma que intento seguir: servir HTML con datos ya obtenidos en el servidor; procesar en el cliente lo que pueda hacerse en el cliente para reducir idas y vueltas al servidor; crear layouts responsivos con el mínimo de CSS y usar JS puro.
Si hace falta, se puede dividir en páginas web separadas.
Pero al parecer, para mis colegas, usar solo HTML, CSS y JS puro suena raro y anticuado.
No le falta nada en particular.
El texto también dice que usar ciegamente solo el lado del servidor no es buena ingeniería de software.
Hay que notar que dice “puede causar problemas”, no “causa problemas”.
Los frameworks de JavaScript del lado del cliente pueden ayudar a crear servicios con interfaces de usuario complejas, pero pueden aumentar el tamaño total de la base de código y empujar el procesamiento al cliente, creando problemas de rendimiento para usuarios con redes lentas o dispositivos de bajo rendimiento.
Pueden hacer que se dependa de código de terceros que el desarrollador no controla, y también pueden exigir cambios grandes en el servicio para adaptarse a cambios del framework.
Si el framework pierde popularidad, también puede ser difícil encontrar gente que lo mantenga.
Si se usa un framework de JavaScript, hay que justificar con evidencia qué beneficio aporta a los usuarios, entender y mitigar los impactos negativos, y evaluar si los beneficios superan los posibles problemas.
Además, debe usarse solo en las partes de la interfaz de usuario que no se puedan construir con HTML y CSS, y cada parte debe diseñarse como un componente independiente.
Si los componentes se separan, incluso si falla la carga de JavaScript, solo falla ese componente, y el resto de la página se carga como de costumbre.