Faites une application offline avec le HTML 5 Application Cache

HTML5
Jérémie Loscos - 02/03/2018 à 00:00:000 commentaire

 

Faire un site web qui marche quand l’utilisateur a une connexion internet c’est pas toujours très simple, mais les choses peuvent se compliquer quand on veut faire un site internet qui n’a pas besoin d’internet.

Là ou avant on pouvait considérer qu’un utilisateur de notre site aurait encore internet la prochaine fois qu’il visiterait notre site, nous somme maintenant dans un monde ou un utilisateur peut perdre sa connexion internet à tout moment.

Les applications mobiles sont habituées à ça et vont souvent fonctionner sans internet, ou à minima afficher un message d’erreur tout en gardant la charte graphique et logo de l’application.

Alors que pour sur des sites internet l’utilisateur va voir ça :

  

C’est drôle quand on veut jouer avec un T-Rex, mais c’est pas forcement ce que l’utilisateur veut faire.

 

 

Heureusement pour nous HTML 5 introduit l’Application Cache qui nous permet de facilement dire aux navigateurs de stocker des ressources pour qu’elles restent accessibles même sans connexion.

https://developer.mozilla.org/fr/docs/Web/HTML/Utiliser_Application_Cache

 

Cette fonctionnalité est deprecated, donc certains navigateurs peuvent indiquer un warning lorsqu’on l’utilise. Mais la fonctionnalité remplaçant l’Application Cache (Services Workers), n’est pas supportée par tous les navigateurs encore. Le HTML 5 Application Cache est la seule solution pour faire une application web ayant mode hors ligne fonctionnant sous Internet Explorer.

 


Principe:

La page web référence un manifest de cache qui déclare les urls des ressources à mettre en cache.

Lorsqu'un utilisateur se connecte pour la 1ere fois à la page, le navigateur télécharge et met en cache toute les ressources référencées par le manifest. Le manifest est également mis en cache.

Lorsque cet utilisateur revient sur la page, le navigateur récupère les ressources depuis le cache et affiche la page. Puis si l'utilisateur est connecté à internet, le navigateur va télécharger le manifest, si celui-ci est différent de la version en cache, le navigateur va télécharger et mettre en cache toute les ressources référencées par ce nouveau manifest. Ces ressources seront utilisées au prochain affichage de la page.


Pour gérer les changements de version du manifest, il est fréquent d'ajouter un commentaire contenant un numéro de version ou date de dernière mise à jour. Comme ça il suffit de changer ce commentaire lorsqu'une modification a été faite pour que le cache soit mis à jour.

 

 Exemple de manifest d'application cache :

CACHE MANIFEST
CACHE:
/Content/bootstrap.css
/Content/Site.css
/Content/Style.css
# commentaire
/Scripts/jquery-1.10.2.js
/Scripts/bootstrap.js
/Scripts/modernizr-2.6.2.js
/Scripts/respond.js
 
/home
/home/index
 
NETWORK:
*

 

Un fichier manifeste doit avoir le mime-type text/cache-manifest et doit obligatoirement commencer par la ligne CACHE MANIFEST. Le manifeste possède une section CACHE qui liste l’ensemble des urls des ressources qui doivent être mise en cache. On peut y mettre n’importe quels types de ressources (style, scripts, images, polices, …) Le manifeste peut aussi posséder une section NETWORK qui indique les ressources que le navigateur ne doit pas mettre en cach. Le caractère * indique qu’on veut que le navigateur récupère toutes les ressources non référencées dans la section CACHE.

La section facultative FALLBACK nous permet d’indiquer url par url une ressources de repli en cas d’absence de connexion internet. Dans le but par exemple d’afficher une joli page d’erreur à la place du T-Rex.

 

Une fois que notre fichier manifest est prêt, il ne nous reste plus qu’a l’inclure dans notre page en le référençant depuis la balise html

<!DOCTYPE html>
<html manifest="~/manifest.appcache">

 

Maintenant lorsqu’un utilisateur se rendra sur ce site, son navigateur téléchargera le manifest et toute les ressources qui y sont référencées :

 

 

 

 

Quand un utilisateur va sur le site, s’il a une connexion internet son navigateur va télécharger le manifest de cache. Si ce manifest a changé, le navigateur va télécharger toutes les ressources indiquées. Sinon il va utiliser les ressources déjà en cache.

Cela permet à un site de s’afficher rapidement dans le cas où l’utilisateur aurait une connexion internet lente. Mais cela implique que s’il y a des changements sur notre site, il faut mettre à jour le manifest sinon les utilisateurs continueront d’utiliser les pages en cache dans leur navigateur.

 

 

  

 


Manifest dynamique

 

Avoir a référencer toute nos ressources dans le fichier manifest peut être assez complexe. Surtout si certaines des ressources qu'on veut mettre en cache ont des urls dynamique. Pour cela on peut générer notre manifest dynamiquement.

Pour illustrer cela regardons le code d'un site en ASP.NET Core qui affiche des articles de blogs.


Les fichier site.js et site.css sont inclus dans la page via le TagHelper de ASP.NET Core, ce qui ajoute un numéro de version à l'url du fichier. Cela est habituellement utilisé pour s'assurer que le fichier est bien retéléchargé par le navigateur lorsqu'il a été modifié. 

Pour inclure ces fichier dans l'application cache il faut mettre l'url complète dans le manifest (c'est à dire en incluant les paramètres de l'url). On peut récupérer le numéro de version d'un fichier via le IMemoryCache d'ASP.NET Core.

 

    public class HomeController : Controller
    {
        private IMemoryCache _cache;
        
        public async Task<IActionResult> AppCacheManifest()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("CACHE MANIFEST");
            sb.AppendLine("CACHE:");
            sb.AppendLine("/lib/bootstrap/dist/css/bootstrap.css");
            sb.AppendLine("/lib/jquery/dist/jquery.js");
            sb.AppendLine("/lib/bootstrap/dist/js/bootstrap.js");
            sb.AppendLine(_cache.Get("/css/site.css")?.ToString());
            sb.AppendLine(_cache.Get("/js/site.js")?.ToString());
            ...
            return Content(sb.ToString(), "text/cache-manifest");
        }
  }


 

De cette manière si un fichier js ou css est modifié, sont numéro de version change ce qui fait que le manifest change et que le fichier sera retéléchargé par les utilisateurs.

Les pages des différents articles de blogs doivent être également accessible en mode hors lignes, il faut donc les ajouter au manifest avec les ressources qu'ils référencent. 


        public async Task<IActionResult> AppCacheManifest()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("CACHE MANIFEST");
            sb.AppendLine("CACHE:");
            ...
            var articles = await _feedService.GetArticles();
            foreach(var article in articles)
            {
                sb.AppendLine("/Feed/ArticleContent?ArticleId=" + article.Id);
                foreach (var url in article.ResourcesUrl)
                    sb.AppendLine(url);
            }
            //Commentaire avec la date de dernière modification
            sb.AppendLine("# LastPublishedDate : " + articles.First().DatePublished.ToString());
            
            return Content(sb.ToString(), "text/cache-manifest");
        }


On inclus une commentaire avec la date de dernières modification des articles pour forcer une mise à jour du cache lors de la modification d'un article.


On a vu que quand le manifest change, les ressources sont téléchargées après que la page ait été affichée. On peut souhaiter que le navigateur utilise la dernière version des ressources dès que possible. Pour cela on peut ajouter ce code javascript qui va forcer un rafraîchissement de la page une fois que toute les ressources ont été téléchargées.

 

function onUpdateReady() {
	location.reload(true);
}

window.applicationCache.addEventListener('updateready', onUpdateReady);
if (window.applicationCache.status === window.applicationCache.UPDATEREADY) {
	onUpdateReady();
}

 

Si cela vous intéresse vous jetter un coup d'oeil au code source ou à la démo

 

 


Inconvénients de l'application cache :


Comme on a vu, avec le HTML5 application cache il est assez facile de rendre un site simple accessible hors connexion. Mais les site ne sont pas toujours simple.

Ce cache à un certain nombre de limitations qui rendent son utilisation dans un gros site compliqué.


-Il n'y a pas d'API javascript permettant de savoir si une ressource est en cache. Par exemple si on voulait désactiver les liens vers les pages pas en caches quand l'utilisateur est hors ligne

-Il serait complexe de gérer un cache spécifique par utilisateur en fonction de ses pages visités ou droits d'accès.

-Lors d'une modification du manifest, c'est l'ensemble des ressources qui sont retéléchargées. Il n'est pas possible d'indiquer quelles ressources ont été modifiées. Un manifest qui change fréquemment peut être couteux en bande passante.

 

Commentaires :

Aucun commentaires pour le moment


Laissez un commentaire :

Réalisé par
Expaceo