DE .NET, SQLSERVER Y MÁS, APRENDE CONMIGO!✔

Desarrollo de todo tipo de aplicaciones y Administración de Base de datos con Tecnología Microsoft


UNETE

Application Cache

0

 



¿Qué es Application Cache?

Esta especificación está pensada para escenarios donde podemos experimentar situaciones en las que no disponemos de conectividad, como en un avión, zonas con poca cobertura, desconexiones intermitentes, etcétera. Hasta ahora con el modo de caché habitual no éramos capaces de obtener recursos a los que no hubiéramos accedido previamente, ni podíamos indicar a qué páginas era posible navegar aún cuando no disponíamos de acceso al servidor, por falta de Internet o porque el mismo no estuviera disponible en ese momento. Pero no sólo los escenarios relacionados con la conectividad son los candidatos de disfrutar de esta API, sino que también nos permite mejorar rendimiento del servidor reduciendo las peticiones de recursos en usuarios recurrentes, manteniendo los más estáticos cacheados en el navegador de forma explícita.

Esta característica está siendo muy utilizada en diferentes escenarios como juegos (como la aplicación de Angry Birds de Chrome Web Store), aplicaciones offline de acceso al correo electrónicoclientes web de música por streaming como Deezer y todas aquellas que puedan trabajar en local y sean capaces de sincronizar su contenido más tarde, o necesiten reducir el flujo de peticiones.

¿Cómo funciona?

Para poder trabajar con App Cache lo primero que debemos conocer es el archivo llamado cache manifest. Se trata de un archivo de texto plano con la siguiente estructura:

CACHE MANIFEST

#version 5.9

 

CACHE:

#This section list all resources that should be downloaded and store locally

 

#HTML files

index.html

 

#JavaScript files

/Scripts/appCache.js

/Content/images/glyphicons-halflings.png

/Scripts/bootstrap.min.js

/Scripts/jquery-1.9.1.min.js

 

#CSS files

/Content/bootstrap.min.css

 

NETWORK:

#This section list all URLs that may be loaded over Internet.

online.html

 

FALLBACK:

#Lists replacements for network URLs to be used when the browser is offline or the remote server is unavailable

/home.html /offline.html

/Content/images/glyphicons-halflings-white.png /Content/offline.png

 

En primer lugar, todo manifiesto debe comenzar con CACHE MANIFEST en la primera línea del archivo, de lo contrario podemos encontrar problemas cuando se intenta procesar por el navegador.

También es importante tener cuidado con los códigos de control que inserta Visual Studio al crear este fichero dentro de una solución, por lo que recomiendo guardar el mismo como Unicode (UTF-8 without signature) – Codepage 65001 a través de File –> Advanced Save Options.

Todas aquellas líneas que comiencen con una almohadilla (#) se tratan de comentarios. A continuación revisamos las siguientes secciones del manifiesto:

 

CACHE

Listado de todos aquellos recursos que deben ser descargados y almacenados localmente.

NETWORK

Lista de todas las URL que necesitan acceso al servidor remoto/Internet. Es posible utilizar el asterisco para indicar que cualquier recurso que no esté listado en el apartado CACHE necesita acceso a la red para acceder a él. Es posible hacer uso de URLs relativasy absolutas.

FALLBACK

En el caso de no tener acceso al servidor remoto se pueden especificar qué recursos deben responder por aquellos que no pueden ser recuperados. Los mismos pueden ser de cualquier tipo (una página HTML, una imágen, código JavaScript, etcétera). El primer parámetro es el recurso al que nos gustaría acceder y el segundo el que tomará su lugar cuando existan problemas de conectividad.

 

Para indicar que un sitio tiene un manifiesto relacionado, basta con asociarlo en la etiqueta html de la página:

<!DOCTYPE html>

<html manifest="manifest.appcache">

<head>

El mismo puede tener el nombre y extensión que se prefiera, pero con convención se sugiere *.appcache. Como MIME type del mismo es recomendable servir text/cache-manifest. Si trabajamos con aplicaciones .NET podemos establecerlo a nivel del archivo web.config de la siguiente forma:

<?xml version="1.0"?>

 

<!--

  For more information on how to configure your ASP.NET application, please visit

  http://go.microsoft.com/fwlink/?LinkId=169433

  -->

 

<configuration>

  <system.web>

    <compilation debug="true" targetFramework="4.5" />

    <httpRuntime targetFramework="4.5" />

  </system.web>

  <system.webServer>

    <staticContent>

      <mimeMap fileExtension=".appcache" mimeType="text/cache-manifest"/>

    </staticContent>

  </system.webServer>

</configuration>

 

Ciclo de vida de Application Cache

Una vez que la página asociada al manifiesto haya cargado, lo primero que el navegador comprobará es si tiene la versión más reciente del manifiesto para ese sitio. De no ser así descargará del servidor la última versión. Una vez obtenida comenzará a descargar todos los recursos nombrados en el apartado CACHE y aquellos que podrían ser utilizados como FALLBACK, en el caso de que no pudiéramos alcanzar el servidor de destino. A partir de este momento se trabajará con los recursos cacheados y no volverán a descargarse hasta que el manifiesto vuelva a sufrir una nueva actualización o limpiemos los datos temporales del navegador.


Si quisiéramos comprobar su efectividad, basta con desconectar el dispositivo de Internet e intentar navegar a aquellas páginas y recursos que fueron nombrados en el manifiesto. Del mismo modo, si intentáramos acceder a aquellos recursos que poseen un fallback, el navegador nos desviaría directamente a aquellas URL indicadas como segundo parámetro.

Eventos

En las versiones más recientes de Chrome (En el momento del post Chrome 26) es posible ver los eventos ocurridos a través de la consola de la herramienta de desarrollo:



No obstante, es posible añadir manejadores a cada uno de ellos con el siguiente código JavaScript:

indow.onload = function () {

 

    //App Cache

    if (window.applicationCache) {

        console.log("Application cache is available");

 

        var appCache = window.applicationCache;

 

        appCache.addEventListener("checking", appCacheHandler, false);

        appCache.addEventListener("downloading", appCacheHandler, false);

        appCache.addEventListener("noupdate", appCacheHandler, false);

        appCache.addEventListener("obsolete", appCacheHandler, false);

        appCache.addEventListener("progress", appCacheHandler, false);

        appCache.addEventListener("error", appCacheHandler, false);

        appCache.addEventListener("updateready", appCacheHandler, false);

        appCache.addEventListener("cached", appCacheHandler, false);

 

        function appCacheHandler(event) {

            var status = appCache.status;

            var msg = null;

 

            switch (status) {

                case appCache.CHECKING:

                    msg = "<span class='label label-warning'>CHECKING</span>";

                    break;

                case appCache.DOWNLOADING:

                    msg = "<span class='label label-info'>DOWNLOADING</span>";

                    break;

                case appCache.UNCACHED:

                    msg = "<span class='label label-inverse'>UNCACHED</span>";

                    break;

                case appCache.OBSOLETE:

                    msg = "<span class='label label-important'>OBSOLETE</span>";

                    break;

                case appCache.IDLE:

                    msg = "<span class='label label-info'>IDLE</span>";

                    break;

                case appCache.UPDATEREADY:

                    msg = "<span class='label label-success'>UPDATEREADY</label>";

                    break;

                default:

                    msg = "UNKNOWN STATUS";

                    break;

            }

 

            var log = document.getElementById("log");

            log.innerHTML += '<li> Event: <span class="label label-inverse">' + event.type + '</span> Status: ' + msg + "</li>";

 

            if (status === appCache.UPDATEREADY) {

                appCache.swapCache();

                if (window.confirm('App cache was updated, you need refresh this page... May I?'))

                    window.location.reload();

                else {

                    log.innerHTML += '<li><span class="label label-important">You need to refresh this page to see the changes!</span></li>';

                }

            }

 

        }

    }

};

 

Lo primero que comprobamos en nuestro código es si Application Cache está soportado por nuestro navegador (las últimas versiones de los navegadores más populares ya lo implementan). Para tener una visión más completa de la disponibilidad de esta característica podemos consultar esta tabla.

En cuanto a los eventos tenemos los siguientes:

checking

Se lanza cuando el navegador está comprobando la última versión del manifiesto alojada en el servidor remoto.

downloading

Indica que el manifiesto ha sido descargado y comienza la obtención de los recursos.

noupdate

Indica que tenemos la última versión del manifiesto y no es necesario descargar ningún recurso.

obsolete

La versión del servidor está obsoleta.

progress

Se lanza por cada uno de los recursos incluídos en la sección CACHE

error

Como su propio nombre indica, se trata del evento reservado para los errores durante la obtención de los recursos indicados en el manifiesto.

updateready

Nos permite conocer cuándo todos los recursos han sido actualizados con la nueva versión. En este ejemplo, además de mostrar el texto correspondiente, hacemos una comprobación al terminar el switch donde verificamos si hemos llegado a este punto y forzamos el cambio de cache a los nuevos elementos a través de la función swapCache(). Si bien esta función nos ahorra una recarga en el sitio, swapCache no nos permite servir los recursos actualizados de manera automática, por lo que debemos preguntar al usuario si podemos refrescar la página para aplicar los nuevos cambios.

cached

Los recursos han sido descargados y la aplicación ha sido cacheada. Este evento sólo ocurre la primera vez que se cachea el contenido. En las siguientes descargas será updateready el que se lance.

También es posible solicitar la actualización de la cache a través de script (sin tener que refrescar la página) utilizando window.applicationCache.update(), aunque será necesario igualmente el swap de la caché y el refresco de la página para poder aplicar los últimos cambios. Suele utilizarse cuando el usuario ha estado trabajando durante mucho tiempo en el sitio sin tener que refrescar la página y recuperar así el nuevo manifiesto durante una recarga.

En este ejemplo la misma función controla todos los eventos posibles y, a través de un switch, muestra además el estado que refleja cada uno de ellos donde curiosamente no tiene por qué coincidir con el nombre del evento. Podemos verlo en la siguiente imagen:



Eventos Online y Offline

Por último, aunque no pertenezca a la API de App Cache, me gustaría mostrar la forma de conocer cuándo una aplicación no dispone de acceso a Internet… ¡Efectivamente! Existe otra API para ello  En este caso debemos hablar de los eventos online y offline pertenecientes al objeto window. A través de la propiedad navigator.onLine podemos conocer cuál es nuestro estado actual e incluso podemos manejar los eventos online y offline de la siguiente manera:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

//Internet status

function isOnline() {

    return navigator.onLine;

}

 

function internetStatus() {

    var className = isOnline() ? "badge-success" : "badge-important";

    var statusName = isOnline() ? "online" : "offline";

 

    var internet = document.getElementById("internet");

    internet.className = "badge " + className;

    internet.innerText = statusName;

}

 

window.addEventListener("online", internetStatus, false);

window.addEventListener("offline", internetStatus, false);

 

internetStatus();

Como podemos ver en el ejemplo, hemos encapsulado el valor de [window.]navigator.onLine en la función isOnline con el objetivo de comprobar dentro de internetStatus cuál es su valor y asociar una clase y un texto a una etiqueta con id “internet” en nuestra página. Además asociamos esta función a los eventos online y offline de window para que, cada vez que ocurran, se vuelta a comprobar el estado de nuestro acceso a Internet. Por último se llama a internetStatus una primera vez al cargar la página para conocer en qué estado nos encontramos inicialmente.

Podéis encontrar más información y demos en la página Appcache Facts.
Existe una página llamada 
Cache Manifest Validator que nos permite comprobar si hemos creado nuestro manifiesto correctamente. De hecho, también disponemos de una extensión para Chrome que realiza la misma función.

DEMOSTRACIÓN

En nuestro Panel de proyecto crearemos tres archivos .html como lo hemos hecho en los ejemplos anteriores, de nombres insex.html, about.html y contact.html como se muestra a continuación


En la página Index.html su código HTML será el siguiente:


En la página About.html su código HTML será el siguiente:




En la página Contact.html su código HTML será el siguiente:


Ahora Procederemos a crear un archivo de texto para nuestro proyecto. En el espacio de nombre del proyecto damos click derecho y seleccionamos Add à New Items

En la siguiente ventana seleccionamos en la parte Izquierda la opción de “General”, Luego seleccionamos el archivo de tipo “TextFile” y en el nombre colocamos “manifest.appcache.text” y le damos click al botón Add.


Allí escribimos lo siguiente:


Y en la etiqueta <HTML> al inicio de nuestro código en las páginas index.html, about.html y contact.html colocamos el manifiesto haciendo referencia a nuestro archivo de texto

Establecemos el archivo Index.html como nuestra página principal


Y la desplegamos (Para este ejemplo uso Google Chrome).



Procedemos a abrir el panel para ver la consola

Fíjese que ya nos muestra información en la caché del navegador


Si le damos click a Network


Y le damos click a las opciones de About y Contact de nuestra página fijesé que se almacena en el caché lo correspondiente a las páginas web










Tal vez te interesen estas entradas

No hay comentarios