Es muy sabido por todos que las aplicaciones web, que hace media década eran el futuro, ya son lo de hoy. Muchos sistemas, aún los privados, ya son desarrollados como aplicaciones web, por las ventajas de accesibilidad que tienen.
El problema es que la tecnología no avanza tan rápido en todos sus ámbitos, y por más modernos que sean los sistemas, en países como el nuestro seguimos teniendo un problema muy grande, que no hemos podido solventar: el pobre ancho de banda.
Las aplicaciones web son conjuntos de páginas web, todas ellas mostrando el contenido que se requiere para realizar cierta actividad, y permitiéndonos manipular datos. Para esto es necesaria la constante comunicación cliente-servidor, pues la información está guardada en un servidor, de ahí la obtenemos y ahí la enviamos de vuelta.
Pero, ¿qué pasa si nuestra conexión a Internet no es lo suficientemente buena? O más correctamente, al menos en México, ¿si nuestra conexión a Internet es pésima? No todos tienen acceso a un ancho de banda de lujo. Hay conexiones por satélite, por teléfono (sí, todavía!), por banda ancha móvil, etc., cada uno con sus propias capacidades, a veces muy limitadas. ¿Y si nuestra aplicación requiere muchas llamadas al servidor?
Somos programadores. No podemos hacer que el Internet sea más rápido (por más que los clientes lo pidan, pueden citarme si quieren). Pero en nosotros cae la responsabilidad de un sistema eficiente para el usuario, y lo que no podemos ahorrar en conexiones a la red, sí podemos ahorrarlo en solicitudes de información, es decir, reduciendo las llamadas al servidor.
Una de las características más recientes de Javascript para este propósito es la de web storage.
Daré un ejemplo muy común: Uno de esos formularios donde el usuario selecciona el país. Al hacerlo, el sistema carga la lista de estados, y al seleccionar uno de estos, carga la lista de ciudades. Normalmente se usa AJAX para hacer esto sin recargar la página completa, y que el usuario no se pierda. Sin embargo, sigue siendo una llamada al servidor, que requerirá una conexión a Internet para enviar la solicitud y descargar la respuesta.
Web storage (almacenamiento web) es una nueva característica que crea dos colecciones de datos de tipo String para Javascript, manipulables a nuestro antojo según la necesidad de la aplicación. Las colecciones son:
- sessionStorage. Guarda los datos que insertemos a lo largo de la sesión, es decir, mientras el navegador esté abierto.
- localStorage. Guarda los datos y los mantiene mientras no borremos la caché del navegador.
Cabe señalar que estas colecciones son propias para un sitio. Las variables que se agreguen en http://www.sitio1.com no podrán ser accesibles desde http://www.sitio2.com.
Suponiendo que el usuario accede a su sesión, sus datos estarán guardados en el servidor (por ejemplo, en .NET, sería dentro del SessionState), pero tal vez ocupamos este dato en el código del lado del cliente, así que podemos hacer esto:
sessionStorage.setItem('usuario', nombre_usuario);
Con esto, el nombre del usuario estará guardado en el web storage para utilizarlo donde sea necesario.
var nombre=sessionStorage.getItem('usuario');
Esta variable estará disponible mientras la sesión esté activa, y se perderá cuando cerremos el navegador.
El uso de localStorage es el mismo, con las funciones getItem y setItem.
Volviendo al ejemplo del principio, tenemos una situación más compleja, pues ya no es un texto el que necesitamos guardar, sino tres colecciones, y debemos recordar que web storage almacena texto.
Imaginemos que mis catálogos son colecciones de objetos como éstas:
var paises=[ {clave:1,nombre:'México'}, {clave:2,nombre:'E.E.U.U'} ]; var estados=[ {clave:1,nombre:'Sonora',pais:1}, {clave:2,nombre:'Chihuahua',pais:1}, {clave:3,nombre:'Arizona',pais:2}, {clave:4,nombre:'California',pais:2} ]; var ciudades=[ {clave:1,nombre:'Hermosillo',estado:1}, {clave:2,nombre:'Álamos',estado:1}, {clave:3,nombre:'Phoenix',estado:3}, {clave:4,nombre:'Los Angeles',estado:4} ];
Podemos usar JSON para guardar y extraer la información en web storage, de esta forma:
//Guardar información en el Local Storage: localStorage.setItem('paises',JSON.stringify(paises)); localStorage.setItem('estados',JSON.stringify(estados)); localStorage.setItem('ciudades',JSON.stringify(ciudades)); //Obtener información de Local Storage: var paises=JSON.parse(localStorage('paises')); var estados=JSON.parse(localStorage('estados')); var ciudades=JSON.parse(localStorage('ciudades'));
JSON define la notación de objetos en Javascript como la que utilicé anteriormente, y es un objeto de Javascript que incluye una función para convertir objetos en cadenas de texto (stringify
) y otra para hacer lo contrario (parse
). JSON.stringify(paises)
se convertiría en esto:
'[{"clave":1,"nombre":"México"},{"clave":2,"nombre":"E.E.U.U"}]'
Ahora que tenemos nuestros catálogos en el localStorage, podemos manipular los elementos de las listas con la selección del usuario, sin necesidad de llamar al servidor con cada cambio.
// Bonus: una función añadida a los arreglos de javascript // para filtrar una lista por el valor de una propiedad. Array.prototype.find(property, value){ var res=[]; for(var i=0; i<this.length; i++){ if(this[i][property] == value) res.push(this[i]); } return res; } document.addEventListener('load',function(){ var sel_paises = document.getElementById('sel_paises'); var sel_estados = document.getElementById('sel_estados'); var sel_ciudades = document.getElementById('sel_ciudades'); sel_paises.addEventListener('change',function(){ var estados = JSON.parse(localStorage('estados')); llenarCombo(sel_estados, estados.find('pais', this.value)); },false); sel_estados.addEventListener('change',function(){ var ciudades = JSON.parse(localStorage('ciudades')); llenarCombo(sel_ciudades, ciudades.find('estado', this.value)); },false); },false);
El llenado de items de la lista será más rápido, pues todo lo hará localmente (en el navegador), sin la necesidad de solicitar la información del servidor.
El límite recomendado por el estándar para web storage en los agentes usuarios es de 5MB, aunque depende de cada navegador el dar mayor o menor espacio. Chrome e IE permiten almacenamiento mayor a 5MB. Opera muestra un diálogo al llegar a esta cantidad, en el cual podemos, como dueños del equipo, aumentar la capacidad si lo consideramos aceptable.
Hay que aclarar que localStorage
y sessionStorage
son las interfaces para guardar y obtener los datos del web storage, pero no se pueden manipular directamente los objetos ahí guardados, únicamente añadir, reemplazar y eliminar. Si quiero modificar un dato en un objeto, debo extraerlo, modificarlo y volver a guardarlo:
var paises=JSON.parse(localStorage.getItem('paises')); paises[0].nombre = 'Estados Unidos Mexicanos'; localStorage.setItem('paises', JSON.stringify(paises));
Por último, para eliminar una variable del web storage (ya que no es sano dejar en memoria elementos en la memoria para siempre… ya mayoría del tiempo), se usa la función removeItem
.
localStorage.removeItem('paises'); sessionStorage.removeItem('usuario');
Un comentario sobre “Web Storage”