Trucsweb.com

Trucsweb.com

HTML

L’optimisation de la programmation Web

RDFFav

HTML5 « Application Cache » pour créer des sites web hors ligne

Consulter votre site hors ligne, simuler une application qui fonctionne sans téléchargement..htaccess,Android, API Javascript,AppCache, Offline,CACHE MANIFEST, FALLBACK, Hors Ligne, iPhone, favicon, Manifest, MIME type, navigator.onLine, NETWORK, Plein écran, swapCache, text/cache-manifest, applicationCache, Web Storage,ononline,onofflineHTML5 « Application Cache » pour créer des sites web hors ligne

HTML5 Stockage hors ligne
HTML5 Offline Storage

Dans la série « Sauver le monde », consulter votre site hors ligne et simuler une application qui fonctionne sans téléchargement à l’aide d’un simple fichier texte dit « manifest » et l’objet HTML5 « Application Cache ». L’application Web mise en cache par le navigateur restera accessible sans connexion Internet. Et ça fonctionne pas à peu près! Vous allez découvrir rapidement à quel point on peut rester coincé avec la vieille version d’une page web même après en avoir vidé la mémoire cache de votre navigateur.

Ce n’est pas que j’aime particulièrement les « applications mobiles ». À vrai dire, quant à moi, c’est une tentative de l’industrie pour reprendre un marché accaparé par le Web libre et le HTML. Thank you Tim! La différence entre une « apps » et un site Web, outre le plein écran et les beaux pictogrammes, c’est qu’il faut la télécharger, s’identifier pour ne pas dire s’inscrire ou carrément la payer pour finalement l’installer. En d’autres mots, garder le pouvoir, le contrôle et vous tenir par les couilles comme au 20e siècle, que dis-je, l’Âge du fer!! Ouf, ça fait du bien à dire!

Cache ou cache pas

La problématique historique est de forcer le navigateur à télécharger la plus récente version disponible sur le serveur. C’est pourquoi la problématique ne nous touchait pas jusqu’à présent. Question de s’assurer d’avoir accès aux dernières données dynamiques bien sur. C’est-à-dire l’ensemble des ressources avec les images et les librairies... Et ce, au gré et aux humeurs de la configuration locale de l’usager. Souvent directement côté serveur ou à l’aide d’entêtes http spécifiques : must-revalidate ou no-cache par exemple.

// Noter que cette balise n’est plus supportée
<META HTTP-EQUIV="Pragma" CONTENT="no-cache" />

L’« Application Cache » c’est tout le contraire. On peut spécifier à la pièce les ressources à stocker. Et depuis, trois idées remettent en question l’ensemble de la gestion des ressources d’une page Web :

  • L’économie d’énergie, pourquoi charger des dizaines de fois un même fichier? Imaginer la rapidité d’affichage et l’économie d’énergie possible en téléchargeant seulement les nouvelles ressources.

  • L’ère de la mobilité nous oblige à considérer la gestion locale des ressources avec autant d’attention que les gestions dynamiques. Le poids, la vitesse, l’espace limité, le caractère intermittent et mobile des communications ou tout simplement les applications natives plus intuitives sur un mobile et toujours disponibles hors connexion.

  • Gestion locale. Et l’idée a tout pour plaire dans la mesure où elle s’harmonise parfaitement avec la philosophie de la gestion locale (XML/RSS, CSS, Javascript/Ajax, Image SVG...). Et du stockage local HTML qui permet lui de stocker localement non pas un fichier HTML mais des données. À la manière du vieux fichier témoin (cookie). Et l’avantage de soulager le serveur de pression tout à fait inutile.

En fait on ne parle plus de mémoire cache mais bien de stockage web ou « Web Storage » local! L’« Application Cache » indique carrément au navigateur de charger la version locale d’un fichier HTML sans même vérifier si une nouvelle version est disponible en ligne. Mieux, on peut aussi indiquer au navigateur quoi faire, fichiers par fichier, du simple favicon à la librairie jQuery. On peut aussi préciser quelles ressources devront être toujours chargées en ligne ou encore quoi faire en cas d’échec (fallback)!

Dans le même ordre d’idée, les trois avantages de la W3C :
  1. Navigation hors ligne - les utilisateurs peuvent utiliser l’application quand ils sont hors ligne ;
  2. Vitesse - les ressources en cache se chargent plus rapidement ;
  3. Réduction de la charge du serveur - le navigateur ne télécharge que les ressources mises à jour et modifiés à partir du serveur.
Internet Explorer et compatibilité

Ben oui! Si la plupart des navigateurs supportent l’« Application cache », il aura fallu attendre la version 10 pour qu’Internet Explorer en fasse de même! (version 11.5 pour Opera). Bon, sur un mobile IE n’est pas la norme et de toute façon. Mais les applications hors ligne sont déjà très bien supportées par les mobiles et autres tablettes tactiles. Et comme toujours avec Internet explorer, tout est transparent, il se contentera de charger la page comme avant sans aucune perte de données.

De l’application à la gestion responsable
5 Mo maximum!

Les navigateurs peuvent avoir différentes limites de taille pour les données en cache mais en général c’est limité à 5 Mo!

Certains navigateurs imposent des restrictions sur le stockage disponible. Avec Chrome par exemple, l’« Application cache » utilise un pool de stockage partagé TEMPORAIRE avec d’autres API hors ligne. Si vous écrivez une application pour Chrome Web Store, utilisez la propriété « unlimitedStorage » pour supprimer cette restriction.

D’entrée de jeu, vous pouvez créer un site Web entièrement consultable hors ligne, ou même simuler une application mobile au complet. Plein écran, avec pictogrammes et des scripts pour récupérer les données localement dans l’attente d’une connexion pour rafraîchir les données via Ajax par exemple.

À première vue facile, l’aventure demande toute une synchronisation. Pour ne donner qu’un exemple, oublier Google Analytic! La compilation des consultation doit être gérée et stocké localement pour être transmise au serveur à la moindre connexion. Justement, s’agit il vraiment d’une visite ou d’une consultation? En ce cas Google va nous sortir un jour une compilation des visites ET des consultations! Pas besoin d’aller jusque là, j’aime bien l’idée d’un accueil, un « splash screen » ou l’identification d’un gestionnaire de contenu soit accessible localement. J’ai un exemple qui s’y prête bien, un site statique neural.quebec qui se contente d’indiquer que le formulaire n’est pas disponible hors ligne. Et qui l’affiche en cas contraire. Tout est local après la première visite.

Concrètement, pourquoi charger un logo, un favicon, une superbe image de fond, une énième librairie jQuery ou un cadre de travail (framework) CSS alors que ces fichiers ne changeront probablement jamais? D’ailleurs en principe ça fonctionne déjà, comme je disais plus haut, c’est même l’inverse. Il faut souvent modifier l’adresse d’un fichier pour obliger le navigateur à charger une nouvelle version d’une feuille de style par exemple :

mafeuille.css?v=2
malibrairie.js?v=3

// Ou une image
monimage.png?v=x

Avec l’« Application Cache » on peut carrément mettre la page HTML en cache et surtout mettre une à une les ressources statiques du site en mémoire cache! Cessons ce verbiage et voyons ça en détail.

Déclaration du fichier « manifest »

Pour ce faire, la page HTML doit faire référence à un fichier dit « manifest file » récupéré par le navigateur en même temps que la page. La référence doit être déclaré à l’aide de l’attribut de la balise <HTML> manifest :

<!DOCTYPE html>
<html lang="fr-CA" manifest="site.manifest">

  <body>
    Contenu de la page...
  </body>

</html>

Le manifeste n’affecte que les pages qui lui font référence. Chaque page du site avec l’attribuer « manifest » forcera donc le navigateur à mettre en cache la page HTML selon les directives inscrites dans le manifeste. Et ce dès la première visite de l’usager. Si l’attribut n’est pas spécifié, la page ne sera pas en mémoire cache et devra être téléchargée à nouveau selon les spécifications d’usage de l’entête HTTP.

Le fichier manifest « .manifest »

Quoiqu’on soit en 2015, le « manifeste » est un banal fichier texte, Apache oblige (le XML connaît pas!). La modernité est bien relative en informatique! Enfin, complètement dépassé mais au moins avec l’avantage d’être plus léger (de quelques bites). Le fichier « manifeste » permet de décrire les ressources à mettre en cache, celles qui devront être rechargées à chaque foi et même un fichier spécifique à ouvrir si la ressource n’est pas disponible. Noter que le URL de la page web n’a pas à être spécifiée dans SON propre fichier .manifest.

Le manifeste a trois sections :

CACHE MANIFEST
La liste des ressources à mettre en cache après le premier chargement, une ressource par ligne.
NETWORK
La liste des ressources qui demandent absolument une connexion.
FALLBACK
La liste des ressources alternatives dans le cas de perte de connexion.

Le fichier « manifeste » doit impérativement commencer par les mots : « CACHE MANIFEST » et déposer sur le serveur dans le même dossier que la page auquel il fait référence. Notez que certain exemple ajoute le mot CACHE: pour la section des ressources hors ligne.

CACHE MANIFEST
 
# Version 0.1

CACHE:
/css/fichier.css
/js/fichier.js
/autrepage.htm
http://www.autredomaine.com/
/images/logo.png
...

FALLBACK:
/ /horsligne.html

NETWORK:
*

Le manifeste ci-dessus liste les ressources à mettre en cache, fichier CSS, Javascript, HTML, image, et même une ressource externe. Une fois le manifeste chargé, le navigateur téléchargera les 4 fichiers à partir de la racine du serveur (/). Une fois fait, la page et ces ressources seront toujours disponibles même hors ligne. Si la ressources n’est pas disponible hors connexion, le navigateur utilisera le « fallback » soit la page « horsligne.html ». Tout autre ressources seront chargé en ligne (NETWORK:*).

NETWORK

La section NETWORK spécifie les ressources qui devront toujours être chargées sur le serveur. Dans l’exemple suivant, le fichier « formulaire.asp » ne devra jamais être chargé en mémoire cache et ne sera donc jamais accessible hors ligne :

NETWORK:
formulaire.asp

// Utilisez l’astérisque pour indiquer au navigateur que toutes autres ressources requièrent une connexion Internet.

NETWORK: *
Le « fallback »

Le « FALLBACK » spécifie tout simplement un fichier de remplacement à ouvrir dans le cas d’échec de la connexion. Dans le cas présent, le fichier « horsligne.htm » sera téléchargé par le navigateur. Le première paramêtre est le URI de la ressources, le second, le fichier de remplacement (fallback) :

FALLBACK:
/html/ /horsligne.htm

Tout ce qui se trouve dans le dossier HTML sera remplacé par la page « horsligne.htm ».


Type MIME
Ajouter le type MIME .manifest sous IIS

Un fichier « manifest » doit être servi avec le type MIME « text/cache-manifest ». Vous devez configurer manuellement le type MIME sur votre serveur ou directement dans le fichier de configuration sous Apache « .htaccess ».

La W3C recommande d’utiliser l’extension « .appcache ». Noter que la W3C n’a rien à voir avec l’« Application Cache » créé par la communauté WHATWG. D’autre part, non seulement plusieurs tutoriel parle plutôt de « .manifest », le serveur IIS l’utilise déjà. Donc sur Apache utiliser « .appcache » sinon utilisez « .manifest ». Mais dans les deux cas vous devez spécifier sur le serveur le type MIME.

Sous « IIS » le type MIME est déjà créé mais avec le mauvais type! IIS utilise « application/x-ms-manifest » que vous devez modifier pour « text/cache-manifest ».

Sous « Apache » il suffit de déclarer le type MIME du fichier « manifest » dans le fichier « .htaccess » :

AddType text/cache-manifest .appcache

Ou dans votre fichier « app.yaml » dans l’application « Google App Engine » :

- url: /mondossierstatic/(.*\.appcache)
  static_files: mondossierstatic/\1
  mime_type: text/cache-manifest
  upload: mondossierstatic/(.*\.appcache)


Mise à jour et vider l’« Application Cache »

Vider le « Stockage local » ne permet pas davantage au navigateur de charger une nouvelle version d’un fichier en « Application Cache ». En fait une fois la page en cache, elle le restera jusqu’à ce que l’un des événements suivants se produise :

  • Le fichier manifeste est modifié ;
  • L’« Application cache » est mise-à-jour à l’aide d’un script.

En CSS on parle de « Mobile first », ici c’est le manifeste en premier et c’est le manifeste qui a le dernier mots! Le navigateur compare bites à bites son fichier « manifeste » avec celui du serveur et le met à jour seulement sous condition qu’il soit différent. Après quoi il peut lire le nouveau manifeste. Comme on peut voir dans l’exemple, il suffit d’indiquer sous forme de commentaires (« # ») la version du manifeste et le tour est joué, en l’occurrence # Version 0.1. Ce qui permet du coup d’indiquer la version de fichier. D’ailleurs il suffit en principe de modifier un seul caractère pour forcer un téléchargement... Vous pourriez par exemple indiquer des versions à partir de la liste des fichiers : style.css?v0.2

En principe! Pendant mes tests, j’ai profité de l’occasion pour optimiser les références et j’ai changé l’adresse (le URL) de mes polices Font Awesome. Et comme ça arrive TOUT LE TEMP en programmation, j’ai oublié de transférer le dossier « fonts » associé à la feuille de styles. J’avais beau changer la version dans mon fichier « site.manifest », rien à faire, mon navigateur Firefox chargeait toujours la même vielle version, avec les mauvais URL, une page sans pictogramme!

Jusqu’à ce que je trouve qu’on peu simplement détruire le fichier « site.manifest » pour forcer le navigateur à recharger la page web.

Mais encore une fois attention, ça démontre la grande force de cette fonctionnalité. Et n’oubliez pas, moi je savais que je devait rafraîchir la page pendant que le fichier est détruit sur le serveur. Il faut impérativement que l’usager recharge la page pendant que le fichier « site.manifest »! En fait pour vous assurer que l’usager qui revient dans deux ans n’aura pas toujours la vielle version, vaut mieux carrément changer le nom physique du fichier « site.manifest ».

ATTENTION

Si le fichier manifeste ou une ressource spécifiée ne parvient pas à être télécharger, l’ensemble de mise-à-jour échouera et le navigateur continuera à utiliser l’ancienne version.

Interface

Simuler une « apps » c’est aussi une question de présentation. Tout d’abord, un beau et gros pictogramme. Tans sous iOS qu’Android, on peut dorénavant déposer les fichiers « icon » directement à la racine du serveur, sans même devoir les déclarer via les métadonnées. L’idée semble excellente à première vue! Personnellement je n’aime pas les objets actifs non déclarés. Et j’aime bien déclarer ce que j’utilise! Et en autant qu’il s’agisse d’une nomenclature ...normalisée. Mais non, il n’y a aucun standard! Chacun fait à sa guise encore une fois et il faut absolument respecter à la lettre les noms de fichiers. Je vous invite d’ailleurs à lire sur le sujet « iOS Developer Library - Configuring Web Applications (meta et icon) »...

Par exemple :

// iOS
apple-touch-icon-114x114.png
apple-touch-icon-120x120.png
apple-touch-icon-144x144.png
apple-touch-icon-152x152.png
apple-touch-icon-152x152.png
apple-touch-icon-60x60.png
apple-touch-icon-72x72.png
apple-touch-icon-76x76.png

// Même chose avec le sufixe « -precomposed »
apple-touch-icon-114x114-precomposed.png
apple-touch-icon-120x120-precomposed.png
apple-touch-icon-144x144-precomposed.png
apple-touch-icon-152x152-precomposed.png
apple-touch-icon-152x152-precomposed.png
apple-touch-icon-60x60-precomposed.png
apple-touch-icon-72x72-precomposed.png
apple-touch-icon-76x76-precomposed.png

// Android
android-icon-114x114.png
android-icon-192x192.png
android-icon-36x36.png
android-icon-36x36.png
android-icon-72x72.png
android-icon-96x96.png

Les pictogrammes iOs seront modifiés par le système, par exemple en ajoutant des coins arrondis ou l’effet de luminosité! Le sufixe -precomposed au contraire permet d’indiquer au système de ne pas modifier le pictogramme. Il s’agit essentiellement de pictogramme de dimensions variables déposé à la racine du serveur. Par chance Google opte pour la manière iOS alors vous n’avez plus à générer les pictogrammes Android. Vous pouvez aussi les déclarer. Voilà l’exemple que j’utilise, avec les balise pour Microsoft :

// Favicon
<link rel="icon" type="image/png" href="/favicon.png" sizes="16x16" />

// iOS
<link rel="apple-touch-icon" href="apple-touch-icon.png" />
<link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png" />
<link rel="icon" type="image/png" sizes="192x192" href="/nice-highres.png" />
<link rel="icon" type="image/png" sizes="128x128" href="/niceicon.png" />

// Microsoft
<meta name="msapplication-TileImage" content="/images/logo-fb.jpg" />
<meta name="msapplication-TileColor" content="#1A1A1A" />
<meta name="msapplication-square70x70logo" content="128px × 128px" />
<meta name="msapplication-square150x150logo" content="270px × 270px" />
<meta name="msapplication-square310x310logo" content="558px × 558px" />
<meta name="msapplication-wide310x150logo" content="558px × 270px" />

// Android (ompatible avec la transparence)
<link rel="icon" type="image/png" href="/android-icon-36x36.png" sizes="36x36" />
<link rel="icon" type="image/png" href="/android-icon-72x72.png" sizes="72x72" />
<link rel="icon" type="image/png" href="/android-icon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/png" href="/android-icon-192x192.png" sizes="192x192" />

L’image d’accueil ou « startup » :

<link rel="apple-touch-startup-image" href="/startup.png" />

Afficher son application en plein écran :

<meta name="apple-touch-fullscreen" content="yes" />

Et enfin indiquer au navigateur qu’il peut traiter la page comme une application avec la couleur de la barre de statut :

<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />

Exemple complet :

<!DOCTYPE html>
<html lang="fr-CA" manifest="site.manifest">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <link rel="apple-touch-startup-image" href="/startup.png" />
    <meta name="msapplication-TileImage" content="/images/logo-fb.jpg" />
    <meta name="msapplication-TileColor" content="#1A1A1A" />
    <meta name="msapplication-square70x70logo" content="128px × 128px" />
    <meta name="msapplication-square150x150logo" content="270px × 270px" />
    <meta name="msapplication-square310x310logo" content="558px × 558px" />
    <meta name="msapplication-wide310x150logo" content="558px × 270px" />
    <link rel="shortcut icon" href="/favicon.ico"></link>
    <link rel="icon" type="image/png" href="/favicon.png" sizes="16x16" />
    ...
  </head>
  <body>
    ...
  </body>
</html>

Manipulation Javascript

L’objet HTML5 window.applicationCache

Cet objet permet de :

  • connaître les états du cache ;
  • attacher des traitements aux événements ;
  • faire une mise-à-jour du cache ;
  • changer le cache actuel.

Constantes, fonctions et événements :

//Fonctions 
update();
swapCache();

//Constantes
UNCACHED = 0;
IDLE = 1;
CHECKING = 2;
DOWNLOADING = 3;
UPDATEREADY = 4;
OBSOLETE = 5;

//Événements
onchecking;
onerror;
onnoupdate;
ondownloading;
onprogress;
onupdateready;
oncached;
onobsolete;

On peut donc par exemple récupérer le statut de l’« Application Cache » à l’aide de la propriété window.applicationCache.UPDATEREADY et ainsi indiquer à l’usager l’état du cache. Voilà un exemple qui détecter le changement de statut de l’« Application Cache » :

var oAppCache = window.applicationCache;
 
oAppCache.addEventListener("updateready", twAjusteCache, false);

oAppCache.update();
 
function twAjusteCache() {
  oAppCache.swapCache();
  alert("Une nouvelle version est disponible.\nVeuillez rafraîchir la page pour mettre à jour.");
}
Tester la connexion avec la propriété « onLine » et les événements « ononline » et « onoffline »

Compatible depuis IE9+(!) mais assez ressent pour la plupart des navigateurs mobile, la propriété Javascript « onLine » et ses deux événements permet d’identifier facilement si la connexion à Internet est disponible :

<p>Internet est : <span id="oConnection">(inconnu)</span></p>

<script>
var bEnLigne = navigator.onLine;
if (bEnLigne) {
  document.getElementById("oConnection").textContent = 'En ligne';
} else {
  document.getElementById("oConnection").textContent = 'Hors ligne';
) 
</script>

Et avec les événements ononline et onoffline

<!DOCTYPE HTML>
<html>
 <head>
  <title>Trucsweb.com - Statut en ligne</title>
  <script>
   function twAjusteStatut() {
     document.getElementById('oConnection').textContent = navigator.onLine ? 'En ligne' : 'Hors ligne';
   }
  </script>
 </head>
 <body onload="twAjusteStatut()" ononline="twAjusteStatut()" onoffline="twAjusteStatut()">
  <p>Internet est : <span id="oConnection">(inconnu)</span>
 </body>
</html>
Cool!

La compatibilité de onLine :

  • Chrome 14+
  • Chrome pour Android 47
  • +IE 9+
  • Navigateur UC pour Android 9.9+
  • Firefox 41+
  • iOS Safari 4.2-4.3+
  • Navigateur Android 2.3+
  • Opera Mini Aucun
  • Safari 5+
  • Opera 15+
  • IE Mobile 10+
  • Edge 12+
Tester votre manifeste

Google Chrome permet d’inspecter le chargement du manifeste dans la console. C’est très pratique pour voir les erreurs, les fichiers manquants. N’oublions pas que l’opération cesse à la première erreur.

Ressources
, Analyste programmeurConception oznogco multimédia (http://oznogco.com), Trucsweb
Dernière mise à jour :

Commentaires

    Ajouter un commentaire
    Votre adresse de courriel ne sera pas publiée. * L'astérisque indique les champs obligatoires.
    Votre évaluation du tutoriel

    10/10 sur 1 revues.
           Visites : 22790 - Pages vues : 23345
    X

    Trucsweb.com Connexion

    Connexion

    X

    Trucsweb.com Mot de passe perdu

    Connexion

    X

    Trucsweb.com Conditions générales

    Conditions

    Responsabilité

    La responsabilité des Trucsweb.com ne pourra être engagée en cas de faits indépendants de sa volonté. Les informations mises à disposition sur ce site le sont uniquement à titre purement informatif et ne sauraient constituer en aucun cas un conseil ou une recommandation de quelque nature que ce soit.

    Aucun contrôle n'est exercé sur les références et ressources externes, l'utilisateur reconnaît que les Trucsweb.com n'assume aucune responsabilité relative à la mise à disposition de ces ressources, et ne peut être tenue responsable quant à leur contenu.

    Droit applicable et juridiction compétente

    Les règles en matière de droit, applicables aux contenus et aux transmissions de données sur et autour du site, sont déterminées par la loi canadienne. En cas de litige, n'ayant pu faire l'objet d'un accord à l'amiable, seuls les tribunaux canadien sont compétents.

    X

    Trucsweb.com Trucsweb

    X

    Trucsweb.com Glossaire

    X

    Trucsweb.com Trucsweb

    X

    Trucsweb.com Trucsweb

    Conditions

    Aucun message!

    Merci.

    X
    Aucun message!
    X

    Trucsweb.com Créer un compte

    Créer un compte

    .
    @