La tête dans le Flux !

RSS
Jan 8

Comment cibler les mobiles de manière optimale ? (bis)

Suite à quelques expérimentations personnelles concernant les performances de chargement des ressources sur smartphones et tablettes, j’en suis venu à reconsidérer ma première méthode de ciblage des mobiles pour tenter de mieux prendre en compte les bonnes pratiques de performances.

Une feuille de style pour les unir toutes

Ma technique initiale se fonde sur une double feuille de styles CSS (styles.css et mobile.css), ce qui est très problématique sur certains périphériques mobiles : les fichiers de styles sont chargés l’un après l’autre et le navigateur attend que le dernier soit chargé avant de poursuivre le chargement de toutes les autres ressources de la page !

Pour résumer la situation, proposer plusieurs feuilles CSS à un périphérique sous iOS (iPhone, iPad) est plutôt désastreux en terme de latence.
Puisqu’il faut se limiter à une seule ressource quelles que soient les conditions, le fichier unique de styles devra cibler tous les médias : mobile, écrans larges, imprimante, etc.

Pour couronner le tout et pour éviter que certaines ressources ne soient chargées puis masquées, il faudra séparer chaque condition exclusivement. Par exemple :

@media (min-width : 641px) { /* appliqué uniquement sur grands écrans */
  body { background: url(concombre_big.jpg); }
  #slideshow { bla bla bla: bli bli bli; }
}
@media (max-width : 640px) { /* appliqué uniquement sur petits écrans */
  body { background: url(concombre_small.jpg); }
  #slideshow { display: none; }
}

Pas de feuille CSS dédiée pour Internet Explorer

Dans cette même logique, il est très judicieux d’éviter de charger une feuille de styles CSS allouée à Internet Explorer.
Pour corriger spécifiquement les déficiences de ce navigateur, il est bien plus intéressant de passer par la méthode des Classes Conditionnelles, comme ceci :

<!--[if lte IE 7]> <html class="ie7 oldie" lang="fr"> <![endif]-->
<!--[if IE 8]> <html class="ie8 oldie" lang="fr"> <![endif]-->
<!--[if gt IE 8]> <!--> <html lang="fr"> <!--<![endif]-->

Après ces deux étapes, il ne devrait y avoir au final qu’un seul fichier CSS à charger pour le navigateur, mais tout n’est malheureusement pas encore fini.

EDIT : et quand-même la version “Commentaires Conditionnels”

Selon les cas (merci aux commentaires reçus), lorsque vos bidouilles pour Internet Explorer nécessitent de longues et nombreuses règles CSS, il peut être pertinent de les conserver sur un fichier externe pour éviter de les faire lire (pour rien) par les autres navigateurs.

Nicolas Gallagher propose (via SASS) une alternative intéressante, basée sur deux feuilles de styles délivrées via deux commentaires conditionnels exclusifs. A vous de trouver la technique qui vous convient le mieux :

<!--[if (gt IE 8) | (IEMobile)]><!-->
<link rel="stylesheet" href="/css/style.css">
<!--<![endif]-->

<!--[if (lt IE 9) & (!IEMobile)]>
<link rel="stylesheet" href="/css/ie.css">
<![endif]-->
Re-EDIT : version “même pas peur” avec des hacks

Dans l’optique de gérer les bogues des anciennes versions d’Internet Explorer (6 à 8) et afin de se prémunir des inconvénients des commentaires conditionnels classiques appelant des feuilles de styles séparées et des soucis de performances dus à des sélecteurs dédiés de type .ie7, rien n’empêche – au cas par cas et avec grande parcimonie – l’usage de deux hacks considérés comme stables et pérennes :

_display : … /* pour IE6 uniquement */
*display : … / pour IE6 et IE7 uniquement */

Des CSS3 Media Queries, mais la compatibilité alors ?!

Distinguer tous les cas de figure au sein d’une même ressource CSS nécessite forcément l’emploi des Media Queries en CSS3, ce qui n’est pas sans conséquences.

En effet, certains navigateurs ne supportent pas cette fonctionnalité CSS3. Notamment les anciennes versions de BlackBerry (avant l’OS6) et d’Internet Explorer (avant IE9 bureau et mobile). Or il est primordial qu’elle soit reconnue sous peine de n’afficher aucun style du tout sur le navigateur défaillant.

Pour Internet Explorer, une solution existe et s’appelle Respond.js.

J’ai toujours été assez réticent envers les bidouilles alternatives reposant sur des scripts JavaScript, mais il faut avouer que Respond est léger (1ko), rapide, bien conçu, et surtout… indispensable pour ma démonstration.

Pour le mettre en œuvre, il suffit de l’appeler directement à la suite du lien vers la feuille de styles CSS, et il s’occupera du reste :

<!--[if lt IE 9]>
<script type="text/javascript" src="respond.min.js"></script>
<![endif]-->

Loin d’être suffisant

Bien évidemment, cette méthode de ciblage n’est qu’une première et mince étape dans un projet de site web mobile.

D’autres points importants sont à prendre en considération dans la quête d’un affichage le plus rapide possible : compression des images, chargement conditionnel des ressources (scripts, images, video), mise en cache, sprites CSS, Data URI, chargement des scripts asynchrone ou différé, HTML5 Web Offline, etc.

Mais ceci est un autre sujet ;)