Los origenes de la tecnología web
Cuando Tim Berners Lee
inventó la web buscaba un sistema para poder publicar y visualizar documentación
científica de forma remota, que fuera atractiva visualmente, fácil de codificar y
fácil de usar para un no informático.
En un documento científico es imprescindible la referencia a otros documentos
citados con el fin de que el lector opcionalmente pueda profundizar en el tema que
se trata.
Por estas razones el Word Wide Web se concibió como un sistema de páginas (documentos)
e hiperenlaces.
Inicialmente la web era un mundo de páginas estáticas y enlaces pero pronto la
generación de páginas dinámicas y en general el uso de la web como soporte para el
diseño de aplicaciones basadas en web lo complicó todo.
La llegada de las aplicaciones web
Durante años ha existido un esfuerzo de adaptar el paradigma de páginas y
navegación entre páginas al desarrollo de aplicaciones, aplicaciones en las que
el concepto de página, como documento estático idéntico para todo el mundo tal y
como lo concibió Berners no existe. Diferentes paradigmas de desarrollo de
aplicaciones web se han ido sucediendo:
- Model 1: la traslación directa del modelo original de páginas e hiperenlaces
en donde las páginas son generada dinámicamente.
- Model 2 o MVC: la navegación entre páginas generadas ya no es directa sino
que es intermediada por un controlador que decide cual es la siguiente página
dependiendo de las operaciones que se hayan realizado en el proceso de transición.
- MVC basado en componentes (¿Model 3?): es la sofisticación del Model 2 en
donde se simula la forma de trabajar en el escritorio, basado en componentes y
eventos, de tal manera que una acción del usuario supone la regeneración de la
página cambiando parcialmente una parte de la misma de acuerdo con la acción.
La página y la transición entre páginas ahora es gestionada por componentes que
saben qué cambios han de realizarse en la regeneración de la página de acuerdo
al evento, simulando un comportamiento similar a los sistemas de componentes
GUI de la programación de escritorio.
En años recientes se ha ido introduciendo la técnica AJAX, dicha técnica con la
ayuda de JavaScript permite el cambio parcial de la página obteniendo nuevos datos
del servidor sin llegar recargarse ésta.
Aunque la práctica del cambio parcial de una página web es muy anterior a la introducción
del componente XMLHttpRequest en Internet Explorer (base de la programación AJAX), ha sido
el uso de este componente el que ha favorecido un uso masivo de la misma.
Hoy millones de sitios web y aplicaciones web usan AJAX para proporcionar una
mejor experiencia al usuario gracias a una mayor inmediatez y transparencia evitando
parcialmente las molestas recargas de páginas.
Sin embargo a pesar del uso masivo de AJAX podemos decir que hoy día la web sigue
un modelo que podríamos calificar de "Model 2 (MVC) enriquecido con AJAX", en donde el
llamado aquí Model 3 tiene cada vez menos sentido, pues la introducción de AJAX hace
en gran parte innecesaria la gestión de páginas basada en componentes. Como habitualmente
el uso de AJAX tiende a estar ligado a componentes (no necesariamente presentes en el
Model 2) podríamos resumir que el estado del arte actual viene a ser un Model 3.5,
en donde la navegación de páginas se consigue evitar parcialmente en el caso de
transiciones de estado menores, las cuales se realizan utilizando AJAX y JavaScript.
¿Qué inconvenientes tiene la navegación y el desarrollo basado en páginas?
Todo programador web sabe lo problemática que es la navegación por páginas en
una aplicación web, aparte del derroche de ancho de banda y de tiempo de proceso en
regenerar la página completa están los problemas con el cacheado no deseado, el
back-forward, los inconvenientes del "form auto fill" habitual en los navegadores etc.
No es raro ver aplicaciones web que ocultan los menues y botones del navegador o que
usan frames o iframes (por ejemplo en bancos) para evitar la problemática de los botones
Atrás/Adelante (Back/Forward).
La programación basada en páginas tiende a forzar una forma de programar extraña,
repetitiva (plagada de includes) e ineficiente (tanto en ancho de banda como en potencia de cálculo)
que no existe en el ámbito del escritorio en donde no existe esa imposición.
¿Qué es lo que impide un uso intensivo de AJAX?
En el ámbito del desarrollo web se suelen distinguir dos tipos de soluciones:
aplicaciones web y sitios web.
En el primer caso AJAX tiende a utilizarse cada vez más de forma intensiva debido
a que este tipo de aplicaciones no tiene algunos de los requisitos de los sitios web,
es en los sitios web en donde un uso intensivo de AJAX puede suponer un problema.
En los sitios web el usuario está acostumbrado al concepto de página, ligados a
las páginas existen algunos requisitos básicos de cualquier sitio web tal y como:
- Memorización de páginas favoritas (bookmarking): cada página web tiene un
único URL, dicho URL es por tanto "memorizable" como favorito. Como AJAX tiende
a cambiar parcialmente las páginas se pierde la posibilidad de guardar favoritos.
- Search Engine Optimization (SEO): la compatibilidad SEO es un deber de cualquier
sitio web, cualquiera puede entender esto. Los actuales robots indexadores de páginas
ven la web como Web 1.0, es decir, el código JavaScript es totalmente ignorado tal que
cualquier cambio parcial de página hecho via AJAX cargando datos del servidor no es conocido
por los robots indexadores que atraviesan el sitio web porque dicha acción no se realiza.
- Servicios basados en visitas de páginas: por ejemplo anuncios y monitorización de visitas
tal y como Google Analytics están basados en el número de veces que una página
ha sido cargada. Por tanto los cambios parciales de páginas hechos por AJAX no cuentan.
- Necesidad ocasional de ventanas emergentes (pop-ups)
Estos requisitos hacen que el uso intensivo de AJAX esté desaconsejado en sitios
web de gran público. Sin embargo la diferencia entre aplicación web y sitio web es
cada vez más sutil, de hecho cualquier sitio web es hoy día una aplicación web.
¿Debemos renunciar a sitios web intensivos en AJAX?
NO.
Hay soluciones técnicas a los requisitos anteriormente mencionados.
¿Es posible el desarrollo de sitios web basados en una Única Página Web (SPI)?
¡SI!
Es el momento de realizar esta transición en las que todos, programadores y usuarios
saldremos ganando. Tenemos la tecnología y los navegadores ya están a la altura para
conseguir este objetivo.
Para ello es preciso compatibilizar el funcionamiento de la técnica Single Page Interface (SPI)
con los requisitos mencionados anteriormente de cualquier sitio web.
Adiós a las páginas bienvenidos los estados
Si en una aplicación web sin JavaScript la sucesión de estados equivale al de
páginas, en una aplicación SPI cualquier cambio parcial de la página supone un
estado (o estado de "la página"). Entre los estados hay que distinguir dos categorías
de estados:
- Fundamentales
- Secundarios
La diferenciación entre ambos tipos de estados es importante, porque los estados
fundamentales serán páginas web cuando sea necesario, serán aquellos estados que
merezca la pena que sean vistos también como páginas web. La distinción entre estados
fundamentales y secundarios dependerá de cada sitio web.
Para entender ambos tipos de estados es conveniente considerar un ejemplo real:
la validación de un usuario a través de login y password.
En una aplicación clásica existirían dos páginas, la propia del login la cual se recargará cuando el login es
incorrecto mostrando además algún mensaje de error, y la página de entrada correcta
mostrando al usuario las posibles opciones.
En una web SPI tanto el estado donde se muestra el login inicial como el estado
de entrada correcta mostrando las opciones podrían considerarse los estados fundamentales,
los estados en donde se muestran los mensajes de error de login mostrando de nuevo el
formulario del login podrían considerarse estados secundarios.
En el caso de un sitio web basado en páginas que se quiere convertir en una web
SPI, los estados fundamentales normalmente serán los equivalentes a las páginas y los
secundarios cuando a partir de un estado fundamental (la antigua "página") se producen
cambios menores que no merecen la pena (por ejemplo) ser memorizados como favoritos o
ser procesados por un crawler.
Single Page Interface y Bookmarking
Diferentes páginas tienen diferentes URLs, si se sigue la ruta SPI ¿cómo cambiar
el estado y la vez la URL para poder ser guardada como favorita sin recargar la página?.
Hay un truco, y es a través de la referencia del URL ("hash fragment", shebang o hashbang), la parte final del URL tras
el carácter #, que sirve para situarse en un punto concreto de la página (a través de
un <a name="ref"></a>). Un cambio en esa parte del URL (si existe) no
provoca la recarga de la página, por lo que al mismo tiempo que cambiamos de estado
fundamental de la página podemos cambiar la referencia del URL a través del objeto
JavaScript window.location sin provocar una recarga. Como el URL cambia al mismo tiempo que el
estado fundamental, el usuario puede memorizar en cualquier momento dicho URL como
"favorito" en su navegador.
Cuando dicho usuario quiere volver en otro momento al estado memorizado como
favorito directamente, el estado objetivo está presente en la referencia del URL,
se producirá una solicitud al servidor, sin embargo dicha referencia por desgracia
no es enviada al servidor porque se considera que no forma parte del URL desde el
punto de vista de las comunicaciones HTTP, por ello es preciso un proceso post-carga.
El servidor devolverá una página inicial en el que no ha considerado el estado
requerido sin embargo el objeto window.location contiene la URL completa de la página
cargada incluyendo la referencia. Si nada más cargar la página se detecta la
presencia de una referencia de estado, vía JavaScript y window.location es posible
reescribir la URL y parametrizarla de forma normal para que vuelva a hacerse una
nueva request al servidor para que sirva la página directamente en el estado
requerido.
Otra opción, mejor que el uso de hashbangs, surge con la llegada de HTML 5, la HTML 5 History API.
Single Page Interface y Search Engine Optimización (SEO)
La forma más sencilla de conseguir que nuestro sitio web sea procesable por los
motores de búsqueda es ofrecer dos modos de navegación diferentes, a los usuarios de
la web como SPI, y a los robots indexadores como páginas.
El siguiente ejemplo de enlace muestra esta idea:
<a href="URL página" onclick="return false">…</a>
Este enlace no hará nada en un navegador con JavaScript activado porque la
navegación está desactivada a través del "return false" del atributo onclick y
sin embargo un robot indexador ignorará el atributo onclick pues el código
JavaScript es ignorado, y considerará el URL especificado como una página a procesar.
En el ámbito de una aplicación SPI, los URLs usados para navegación de estados/páginas
deberán contener el estado destino, el mismo tipo de URL que usamos en bookmarks (utilizando una
referencia para indicar el estado) o directamente indicando el estado como un
parámetro, esta última opción es la preferida pues evita una solicitud al servidor,
por supuesto siempre es posible utilizar "pretty URLs" para este fin.
Actualmente Google ya procesa "AJAX URLs", es decir, URLs conteniendo el estado objetivo
en la referencia de la URL siguiendo #! como se especifica en
Making AJAX Applications Crawlable,
en este caso el sitio web/aplicación debe devolver la página solicitada en este caso a través
de un parámetro _escaped_fragment_.
Al mismo tiempo el framework SPI puede añadir código específico al onclick
antes del return false o asociar un "event listener" al enlace
registrándolo a través de addEventListener o attachEvent dependiendo del navegador,
dicho event listener podrá estar vinculada a una acción que se comunique con el
servidor via AJAX para efectuar el cambio de estado. Cuando se pulse el enlace dicho cambio de estado no será
una carga de una nueva página pues el atributo onclick="... return false"
impide el comportamiento por defecto del enlace.
La técnica descrita es la más sencilla e inmediata a través de enlaces visibles compatibles
con robots y con SPI, siempre es posible separar ambas funcionalidades utilizando enlaces ocultos para el usuario
pero visibles para los robots junto con otro tipo de elementos "pulsables" para efectuar
las transiciones de estado SPI a través de JavaScript, los cuales serán invisibles para los robots.
Es fundamental que el framework web servidor tenga la capacidad de generar la
página web en el estado requerido como HTML en tiempo de carga, pues lo normal es
que la transición de estados tras la carga se realice a través de JavaScript con
cambios parciales de página.
Esta dualidad entre renderización parcial de estados via JavaScript y como HTML en
carga directa de estado son requisitos imprescindibles para conseguir un sitio web
SPI y a la vez capaz de simular páginas.
SPI y los botones Atrás/Adelante
Los botones Atrás/Adelante son una fuente de problemas en sitios web basados en páginas
y deberían ser evitados lo más posible. A pesar de que los usuarios finales están acostumbrados
a evitar los botones Atrás/Adelante cuando están enviando un formulario de datos (porque conlleva
el riesgo de comprar dos veces el mismo producto), el uso de los botones Atrás/Adelante
es enormemente popular.
Aparentemente el paradigma SPI rompe la tradicional forma de navegar en un sitio web,
porque en teoría los botones Atrás/Adelante no tienen sentido en SPI (no hay páginas) y los
navegadores web no proporcionan un buen control de estos botones.
Esto no es totalmente cierto, el comportamiento de los botones Atrás/Adelante
puede ser simulado, en vez de navegación por páginas, Atrás/Adelante (y la navegación
en general por la historial del navegador) puede ser usado para cambiar el estado
actual al previo/siguiente estado. En este caso un código JavaScript puede detectar
cuando la parte "referencia" de la URL cambia y solicita a la aplicación que cambie
el estado al especificado en la URL. Debido a que el navegador no cambia la página,
tu aplicación es ahora totalmente responsable del comportamiento del Atrás/Adelante
evitando los típicos problemas del uso de Atrás/Adelante cuando se envía un formulario
de datos, ahora en SPI no hay tal formulario y no hay navegación por páginas no controlada
por la aplicación/sitio web.
SPI y los servicios basados en visitas a páginas
Los servicios de anuncios o los contadores de visitas a páginas están basados en
cargas de páginas. En ambos casos es posible usar elementos ocultos <iframe>
conteniendo una página web con los scripts requeridos por dichos servicios.
En el caso de los servicios de anuncios tal y como Google AdSense la inserción
dinámica del <iframe> supondrá la carga de los anuncios por lo que cada cambio
de estado puede suponer una nueva carga o inserción dinámica del <iframe>. Google AdSense parece
detectar cuando el script de AdSense es ejecutado dentro de un <iframe> y
tiene en cuenta el contenido del la página contenedora. Puede ser conveniente añadir
algún tipo de parámetro que identifique el estado fundamental que está cargando el
<iframe>.
En el caso de los scripts de visitas, podemos utilizarlos como monitorización de
visitas a estados fundamentales de nuestra sitio web SPI. En este caso el
<iframe> oculto contendrá una página web normal que simplemente
contiene los scripts de control de visitas, a través de un parámetro podremos indicar
al script qué estado fundamental estamos visitando. Dicho <iframe> es
conveniente que sea un elemento global que es introducido en la página una sola vez.
Cuando un estado fundamental es cargado a través de una URL, el <iframe> de control de visitas convendrá
que tenga como parámetro la información del estado siendo cargado. Tras la carga
inicial cualquier cambio de estado podremos notificarlo
cambiando la URL via JavaScript de acuerdo con el nuevo estado, dicho cambio provocará una recarga
del <iframe> de visitas memorizando dicha visita al estado.
SPI y las ventanas pop-up
La creación de una nueva ventana supone claramente una ruptura con el modelo SPI,
pero no hay que ser fundamentalista, si el estado de dicha ventana no interfiere en
el estado de la página que la creó, nada hay de malo en el uso de ventanas pop-up
como páginas normales.
El problema surge cuando las acciones realizadas en una página "pop-up" influyen
en la página padre, ya sea dicha página/ventana modal o no modal, la coordinación
entre páginas es complicada. Por ejemplo no hay un estándar web para gestionar páginas web modales respecto a otra página,
pues el concepto de página tradicionalmente ha sido siempre el de un elemento
autónomo y por tanto su ciclo de vida es difícilmente coordinable desde otra página.
Este problema desde hace tiempo tiene solución en SPI y consiste en la simulación de
ventanas modales o no modales dentro de la misma página web sin necesidad de crear
nuevas páginas. En el caso de las ventanas no modales cualquier elemento HTML con
posicionamiento absoluto pasa a ser una "ventana no modal" y la modalidad se
consigue a través del adecuado uso del posicionamiento absoluto, el control del
z-index y la opacidad respecto a las capas ("layers") inferiores. Estas soluciones
son las deseadas en un ambiente SPI.
Con un poco de esfuerzo, incluso el estado en el que se muestra una ventana modal
puede ser un estado fundamental y por tanto procesable por los buscadores de páginas.
Un cambio cultural del programador web
La mayoría de los programadores (y frameworks web) piensan en una web basada en
páginas, la eliminación de las páginas supone un cambio radical en el modo de hacer
sitios y aplicaciones web. Este cambio ya no es tan radical gracias a que la popularidad
de AJAX hemos reducido el número de páginas de nuestros sitios web y en resumen
nos ha acercado poco a poco a este "nuevo" modelo de programación SPI.
En la nueva web SPI desparece el tag <form> y en general la necesidad de la sesión
usada como coordinadora de datos entre secuencias de páginas, debido a que el protagonista pasa a ser
únicamente la página cliente con algún tipo de simetría en el servidor (la página en el servidor).
De hecho, la eliminación de la necesidad de coordinar páginas a través de la sesión elimina otra
fuente de problemas tal y como es la práctica de algunos usuarios de abrir varias ventanas con la
misma página en aplicaciones web que suelen corromper la sesión y la aplicación en general.
La forma de programar SPI es basada en eventos de forma totalmente similar a como
se hace en el escritorio en donde la gran mayoría de las aplicaciones suelen ejecutarse
dentro de la misma ventana principal y cuando existen ventanas hija, éstas son
plenamente controladas por la ventana principal y verdaderamente modales.
Siguiendo la evolución de paradigmas de desarrollo web, podríamos denominar Model 4
a esta "nueva" forma de construir sitios web.
Un cambio cultural del usuario?
No mucho, a través del soporte de favoritos y la simulación del funcionamiento
de los botones Atrás/Adelante, los usuarios finales apenas van a apreciar la
diferencia entre un sitio web SPI y el mismo basado en páginas, es más lo que
percibirán es que el sitio SPI responde con mucha más prontitud
y se eliminan los típicos parpadeos y el "scroll" de cambio de página.
Viabilidad técnica hoy
Este manifiesto no es una declaración de intenciones sino la expresión de la
voluntad de promover una "nueva" forma de construir sitios web que es ya real. Las
consideraciones técnicas anteriores han tenido siempre el framework web Java
ItsNat como base tecnológica
en el desarrollo de sitios web SPI. A pesar de que ItsNat fue concebido desde el
primer día pensando en este tipo de aplicaciones, las técnicas anteriormente
mencionadas pueden ser desarrolladas en otros framework web, o bien dichos
frameworks podrían evolucionar hacia la posibilidad de realización de este tipo
de sitios web SPI con requerimientos de simulación de páginas.
Algunas características deseables de los sitios web SPI para que puedan ser
substitutivos de los sitios webs tradicionales basados en páginas, tal y como la
simulación de páginas a través de estados fundamentales en carga, sólo son posibles
en frameworks web céntricos en el servidor, en donde la renderización HTML se
realiza en el servidor en tiempo de carga. Es la posibilidad de renderización de estados
fundamentales como HTML en tiempo de carga y a la vez por inserción parcial a través de
JavaScript, las características clave de un framework apto para la realización de
sitios web SPI. Los frameworks céntricos en el cliente pueden tener un papel muy
relevante para la realización de los llamados estados secundarios en este documento.
Ejemplo real
La web Innowhere.com
realizada con ItsNat en el servidor es un buen ejemplo de sitio web SPI porque
resume las características exigidas a una web SPI, de acuerdo con este documento,
para poder ser substituta de forma satisfactoria de una web tradicional.
De hecho la nueva versión SPI reemplaza sin cambiar significativamente estética
y funcionalidad, la versión anterior basada en páginas.
Características:
- Single Page Interface: los botones Atrás y adelante son simulados
cambiando al estado visitado previo o siguiente.
- Los estados fundamentales pueden ser memorizados como Favoritos (bookmarks)
- SEO compatible: los estados fundamentales son accesibles por navegación por
páginas si desactiváramos JavaScript en el navegador, incluso una ventana modal
- Compatible con el sistema de "AJAX URLs" de Google usando el formato
#!, la página
puede ser también solicitada usando el parámetro _escaped_fragment_ de acuerdo con la convención de Google.
Por ejemplo este estado es procesado por Google
solicitando este URL.
- Funciona con JavaScript desactivado.
- Muestra un banner con publicidad de Google AdSense
- A pesar de ser SPI, la navegación por los estados fundamentales es
monitorizado por Google Analytics a través de un <iframe> oculto cuyo URL
cambia indicando el estado visitado
- Usa simulada ventana modal evita crear una nueva página, esta ventana también es
accesible directamente a través de un URL
y por tanto el contenido es SEO compatible.
El Manifiesto en otras lenguas
Inglés
Ruso gracias a Andrey Geonya, puede estar ligeramente desactualizado porque este manifiesto está "vivo".
Enlaces al manifiesto
Noticia en JavaHispano.org
Noticia en DZone
Noticia en TheServerSide.com
Discusión en YCombinator.com
Autor del manifiesto: Jose María Arranz Santamaría