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/html
1px=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-width
input
)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" />
handheld
handheld
handheld
Inutile 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.innerWidth
RewriteCond %{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 GMT
Cache-Control: max-age
qui précise une date relative à la date de requête du document
Cache-Control: max-age=300
pour 5mnType 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 GMT
ETag
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-Agent
Accept-*
(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-Agent
Les 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)