This project is funded by the European Union through the Seventh Framework Programme (FP7/2010-2012) under grant agreement n°257800
- Mobile Web Applications (MobiWebApp)

« Vous… vous avez un écran… heu… un écran… très petit »
Cyrano de Bergerac, Acte I scène 4
(version mobile)
En moyenne :
Dans tous les cas, les saisies sont difficiles sur un terminal mobile.
Trois méthodes principales pour interagir avec du contenu :
| Réseau | Bande passante moyenne | Temps nécessaire pour télécharger 100Ko |
|---|---|---|
| GSM | 10 Kb/s | 1 mn 20 s |
| GPRS | 50 Kb/s | 16 s |
| EDGE | 180 Kb/s | 4.5 s |
| 3G | 380 Kb/s | 2.1 s |
| 3G+ | 1 Mb/s | 0.8 s |
| Wi-Fi | 30Mb/s | 26 ms |
NB : 100Ko peuvent très bien coûter $1 !
| Réseau | Latence | Latence pour 10 échanges |
|---|---|---|
| GSM | 1 s – 2 s | 10 s – 20 s |
| GPRS | 600 ms – 700 ms | 6 s – 7 s |
| EDGE | 300 ms – 500 ms | 3 s – 5 s |
| 3G | 100 ms –300 ms | 1 s – 3 s |
| 3G+ | 50 ms – 150 ms | 500 ms – 1 500 ms |
| Wi-Fi | 1 ms – 5 ms | 10ms – 50 ms |
(feature phones, smartphones, flip, barres, écran allongé, etc.)
Quels sont les types de terminaux présents dans la salle ?

Géolocalisation:
navigator.geolocation.getCurrentPosition(…)
Accéléromètre / Gyroscope:
addEventListener('devicemotion', …)
Etat de la batterie:
battery.addEventListener('batterylow', …)
Caméra / Micro:
navigator.getUserMedia('video,audio',…)
S’adapter au type de connexion:
if (navigator.connection.type) == "3g") { … }
Faire du « push » :
var eventsource = new EventSource();
eventsource.onmessage = function(event) { … }
Communications client-server bi-directionnelles :
var socket = new WebSocket(
'ws://game.example.com:12010/updates');
socket.onopen = function () { …};
Plus tard, connexions P2P (et communications temps réel) :
var connection = new PeerConnection(
'STUNS example.net',
signalingCallback);
Plus tard, interactions entre terminaux:

Au final…
Il ne peut en rester qu’un !
Maintenir une séparation nette entre les technologies :
Il est plus facile de partir de fondations solides et de rajouter quelques extensions que de devoir supprimer certaines fonctionnalités après-coup.
application/xhtml+xml@media et les types de media.text/html1px=0.75pt
1pt=1/72in
1em=14/16px (fixé par font-size)cm et le px !)1cm CSS = 1cm réel)![]()
Pour un smartphone, si cette définition est bien suivie :
viewport<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Forcer la largeur du viewport</title>
<meta name="viewport" content="width=418,initial-scale=1.0" />
</head>
<body>[…]</body>
</html>
<meta name="viewport"
content="width=device-width,initial-scale=1.0" />
margin-*, padding-*, line-height, font-size
width et min-widthinput)| Media type | Description |
|---|---|
| all | Pour tous les terminaux, valeur par défaut |
| screen | Pour les écrans d’ordinateurs classiques |
| handheld | Pour les écrans de terminaux mobiles |
| Pour l’aperçu avant impression et l’impression | |
| projection | Pour la projection de transparents |
@media handheld {
body { margin: 0; }
h1 { font-size: 1.3em; }
}
@import url("mobile.css") handheld;
media<link rel="stylesheet" href="mobile.css" media="handheld" />
handheldhandheldhandheldInutile d’utiliser handheld au final !
Les requêtes de média CSS étendent les media types avec des critères supplémentaires :
width : largeur de la fenêtre d’affichagedevice-width : largeur de l’écranheight : hauteur de la fenêtre d’affichagedevice-height : hauteur de l’écranaspect-ratio : width / heightorientation : portrait ou paysageLes propriétés numériques se préfixent avec min- et max-.
width ou device-width ?width parce que la propriété est indépendante du terminal.
C.f. Media Queries (une liste de sites qui utilisent les CSS Media Queries)
viewport)<meta name="viewport"
content="width=device-width,initial-scale=1.0" />
<link rel="stylesheet" type="text/css"
href="base.css" />
<link rel="stylesheet" type="text/css"
href="deuxcol.css"
media="only all and (min-width: 600px)
and (max-width: 800px)" />
<link rel="stylesheet" type="text/css"
href="troiscol.css"
media="only all and (min-width: 801px)" />
<!--[if lt IE 9]>
<![if !IEMobile]>
<link rel="stylesheet" type="text/css"
href="troiscol.css" />
<![endif]>
<![endif]-->
window.innerWidthRewriteCond %{HTTP_USER_AGENT} " MSIE " [NC]
RewriteCond %{HTTP_USER_AGENT}
"Windows Phone| IEMobile" [NC]
RewriteRule ^troiscol.css$ [F,L]
Dans l’ensemble, ces bibliothèques sont lourdes pour les navigateurs mobiles (31Ko pour la version compressée de JQuery par exemple).
"use strict";<a href="javascript:clic();">Argh !</a>
document.getElementById("bouton")
.addEventListener("click", clic);XMLHttpRequest en particulier)if (window.navigator.geolocation) {
// Interface de géolocalisation disponible
[…]
} else {
// Pas d’interface de géolocalisation disponible
[…]
}
Les navigateurs bloquent temporairement le chargement d’une page lorsqu’ils rencontrent un script.
Grouper les scripts à la fin du contenu HTML lorsque c’est possible :
<html>
<head>
<!-- Pas de script ici -->
</head>
<body>
<script type="text/javascript" src="scripts.js"></script>
</body>
</html>
onmouse !
load, click, change, submit)| Réseau | Bande passante moyenne | Temps nécessaire pour télécharger 100Ko |
|---|---|---|
| GSM | 10 Kb/s | 1 mn 20 s |
| GPRS | 50 Kb/s | 16 s |
| EDGE | 180 Kb/s | 4.5 s |
| 3G | 380 Kb/s | 2.1 s |
| 3G+ | 1 Mb/s | 0.8 s |
| Wi-Fi | 30Mb/s | 26 ms |
NB : 100Ko peuvent très bien coûter $1 !
| Réseau | Latence | Latence pour 10 échanges |
|---|---|---|
| GSM | 1 s – 2 s | 10 s – 20 s |
| GPRS | 600 ms – 700 ms | 6 s – 7 s |
| EDGE | 300 ms – 500 ms | 3 s – 5 s |
| 3G | 100 ms –300 ms | 1 s – 3 s |
| 3G+ | 50 ms – 150 ms | 500 ms – 1 500 ms |
| Wi-Fi | 1 ms – 5 ms | 10ms – 50 ms |
Pour afficher une page Web:
cat script1.js script2.js > script.js@media !)<img src="http://nom1.example.com/img1" />
<img src="http://nom1.example.com/img2" />
<img src="http://nom1.example.com/img3" />
<img src="http://nom2.example.com/img4" />
<img src="http://nom2.example.com/img5" />
But :
convert de la suite ImageMagickDifférents types de caches :
Il suffit de répondre à deux questions :
C.f. « Un tutoriel de la mise en cache » de Mark Nottingham (en français).
Spécifiée dans deux en-têtes HTTP, souvent utilisés ensemble :
Expires qui précise une date absolue
Expires: Tue, 14 June 2011 15:19:00 GMTCache-Control: max-age qui précise une date relative à la date de requête du document
Cache-Control: max-age=300 pour 5mn| Type de document | Durée | Directive Cache-Control |
|---|---|---|
| Static HTML page | 1 semaine | Cache-Control: max-age=6004800 |
| Dynamic HTML page | 1 heure | Cache-Control: max-age=3600 |
| « Real-time » HTML page | 2 minutes | Cache-Control: max-age=120 |
| CSS, image, script | 1 mois | Cache-Control: max-age=2592000 |
Spécifiée dans deux autres en-têtes HTTP, souvent utilisés ensemble :
Last-Modified qui précise la date de dernière modification
Last-Modified: Mon, 13 June 2011 10:21:00 GMTETag qui precise un numéro de version
ETag: "dakar-42"La version peut aussi s’inclure dans le nom du document :
<script type="text/javascript" src="script-v1.7.js">
</script>
Par exemple, sous Apache :
# Enable the mod_expires module
ExpiresActive On
# Set expiration date per document type
ExpiresByType text/html "access plus 1 week"
ExpiresByType text/css "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
TOUT ce qui peut l’être
(HTML, CSS, images, scripts, contenu AJAX, etc.)
Accept-Encoding envoyé par le navigateurContent-Enoding envoyé au navigateurSous réserve d’activer le module mod_deflate :
AddType .htmlc text/html
AddEncoding gzip .htmlc
Data storage:
window.localStorage
Better, but later:
var db = window.indexedDB.open(dbname);
HTML5 Application Cache:
<html manifest='manifest_file'>
Accept-*User-AgentAccept-* (Accept, Accept-Charset, Accept-Encoding, Accept-Language) qui précisent certains paramètres du navigateurUser-Agent qui identifie le navigateur (mais pas uniquement)X-WAP-Profile qui identifie le terminal (mais pas uniquement)Accept-*Sous Apache :
Options +MultiViews
En supposant la requête suivante :
GET /img HTTP/1.1
Host: example.com
Accept: text/html,image/png,image/jpeg;q=0.8
[…]
Le serveur cherche img.png, puis img.jpg dans le répertoire demandé.
User-AgentLes chaines User-Agent:
Il y a des dizaines de milliers de possibilités.
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} "android" [NC]
RewriteRule ^/$ /index-android.html [L]
RewriteRule ^/$ /index.html [L]
Header merge vary "User-Agent"
Les bases de decription de terminaux fournissent ce genre d’information :
http://www.w3.org/Mobile/training/
Prochains cours en Janvier/Février 2012
Twitter: @W3Training
This project is funded by the European Union through the Seventh Framework Programme (FP7/2010-2012) under grant agreement n°257800
- Mobile Web Applications (MobiWebApp)