Alsacreations.com - Apprendre - Archives (juillet 2013)

Les dernières ressources publiées sur Alsacreations.com

Le: 31 07 2013 à 10:00 Auteur: Raphael

LearnLayout est un mini-site d'apprentissage dédié au positionnement en CSS.

Parfaitement adapté aux débutants (display, modèle de boîte, float, position, inline-block), le tutoriel n'exclut pas les intégrateurs chevronnés puisqu'il aborde des sujets avancés tels que clearfix, box-sizing, media queries, multicolonnes, flexbox et les frameworks CSS.

Le: 27 07 2013 à 13:50 Auteur: dew

Les navigateurs rivalisent d'ingéniosité pour diminuer le temps de chargement des pages, ou du moins le faire ressentir à l'utilisateur. Quelques tentatives de pré-chargement automatique furent réalisées dans le passé, sans toutefois rencontrer un succès immédiat. En effet, effectuer une requête nécessite de "deviner" par avance quelles pages seront les plus pertinentes à pré-charger, avec plus ou moins de justesse et de risques :

  • cela consomme de la bande passante - peut-être inutilement si le visiteur décide de ne pas continuer sa navigation dans le sens de l'anticipation
  • cela consomme des ressources locales (mémoire vive, disque dur, etc)
  • cela peut fausser les statistiques du serveur si elles n'ignorent pas ces requêtes

Désormais, des moteurs de navigateurs courants tels que Firefox, Internet Explorer 9/10/11+ et Chrome peuvent exploiter les directives de la balise <link> et de l'attribut rel (relation) avec certains mots-clés pour pré-charger des URLs précises, que ce soit du code HTML, CSS, JavaScript, images, etc.

Ces techniques sont à utiliser avec une extrême précaution. Mal employées, elles peuvent vous causer plus de tort que de bien et gêner vos utilisateurs (voir les différents cas évoqués précédemment).

Prefetch

Une relation prefetch va déclencher le pré-chargement du fichier mentionné par le lien (attribut href), afin de le placer en cache.

Cette instruction figure dans la spécification côté WhatWG (Links) et W3C (HTML5 Links). Elle est supportée par Mozilla Firefox, Chrome et IE9+.

<link rel="prefetch" href="http://www.mondomaine.com/autre_page.html">
<link rel="prefetch" href="http://www.mondomaine.com/autre_feuille_de_styles.css">

On ne peut pas spécifier d'adresse globale de répertoire, de caractère joker (*), de fichier à télécharger/enregistrer, ou d'autre protocole que http/https. Ne passons pas à côté des choses simples.

Il faut se servir de cette directive avec parcimonie pour ne pas pénaliser la bande passante du visiteur (qui est peut-être sur du bas-débit/mobile) et du serveur. De toute manière, les navigateurs imposent des limites ; par exemple Internet Explorer 11 ne tolère que 10 ressources pré-chargées.

Quand utiliser prefetch ?

Lorsque la navigation logique de l'utilisateur a toutes les chances d'aboutir sur un lien précis, par exemple :

  • Lorsqu'il consulte une suite de pages (présentation, slideshow, slides, résultats de recherche paginés...) et qu'il y a une forte probabilité qu'il passe à la suivante.
  • Pour anticiper des images ou des feuilles de styles qui auront toutes les chances de s'afficher sur les pages principales du site, ou de l'application web.

Tests et vérifications

Comment distinguer une requête envoyée au serveur pour un pré-chargement d'une consultation réelle ? Le navigateur peut le signaler avec un en-tête HTTP supplémentaire. Par exemple Firefox envoie X-moz: prefetch, qui pourra se retrouver avec PHP dans $_SERVER['HTTP_X_MOZ'] mais ceci peut évoluer au cours du temps et n'est pas standardisé.

Tous les bons outils de développement (Firebug, F12, etc) pourront afficher les requêtes partant vers le serveur.

La spécification précise également que l'on peut placer cette relation avec les éléments <link>, <a> et <area>.

Dns-prefetch

Dans ce cas, le pré-chargement sera en réalité une requête DNS menée par anticipation, pour résoudre un nom de domaine en adresse IP, sans attendre de le rencontrer dans le code source de la page ou d'une page suivante. Ces requêtes peuvent parfois nécessiter quelques dizaines de millisecondes, et il y en a d'autant plus qu'un document fait appel à des ressources issues de domaines variés.

Note : Cette instruction n'est pas encore standardisée. Elle est reconnue par Mozilla Firefox, Google Chrome et IE10+.

<link rel="dns-prefetch" href="http://www.autredomaine.com/">

Ou sans protocole :

<link rel="dns-prefetch" href="//www.autredomaine.com/">

Si l'on sait par avance que www.mondomaine.com fera ultérieurement appel à des pages, images, CSS, JavaScript de www.autredomaine.com, ou de cdn.mondomaine.com, il pourra être utile de tenter de prédire ce comportement et de gagner du temps sur les requêtes DNS qui seront nécessaires pour convertir ces différents domaines ou sous-domaines en adresses IP (entre 50 et 250 ms généralement).

Certains navigateurs - notamment Chrome - utilisent aussi cette fonctionnalité sans vous demander votre avis et sans déclaration explicite dans un code HTML ; par exemple selon l'historique de l'utilisateur (les 10 derniers domaines visités avant fermeture) et/ou par diviniation de ce qu'il va taper dans la barre d'adresse. Pour voir quelques statistiques DNS sur ce moteur, consultez la page chrome://dns/

Prerender

Le pré-rendu de document va passer la main au moteur d'interprétation pour mettre en cache (mémoire) par avance une page afin de l'afficher quasiment instantanément si le visiteur y accède en ayant déjà un "rendu graphique".

Note : Cette instruction n'est pas encore standardisée. Elle est reconnue par Google Chrome et IE11+.

<link rel="prerender" href="http://www.mondomaine.com/autre_page.html">

Dans ce cas de figure, l'API PageVisibility pourra être utile pour se renseigner sur l'état précis du rendu de la page avec la propriété document.visibilityState (alors égale à prerender). On peut ajouter dans la valeur de l'attribut rel le mot-clé prefetch pour les navigateurs le supportant mais pas encore prerender.

Pour citer un exemple, Internet Explorer 11+ ne pré-calcule qu'une page à la fois. Il agit aussi intelligemment en n'exécutant cette instruction que si le document y faisant appel est au premier plan (onglet actif) et visible. La page de destination est effacée de la mémoire, entre autres :

  • si le visiteur décide de diriger ses clics vers une autre URL
  • s'il n'y accède pas dans un délai de 5 minutes
  • s'il change de fenêtre/onglet actif
  • si l'adresse renvoie une erreur HTTP (famille des 400, 500, etc)
  • si la page destination utilise <audio> ou <video>

On retrouve ces conditions du côté de Google Chrome, qui y ajoutera aussi une annulation en cas de :

  • demande d'identification HTTP ou de page HTTPS
  • création de popup
  • ressources système trop occupées
  • requête AJAX (XMLHttpRequest) avec méthode PUT/POST/DELETE
  • navigation privée

Ce navigateur permet d'examiner l'activité du pre-rendering via la page interne chrome://net-internals/#prerender. Il n'y a (a priori) pas d'en-tête HTTP spécifique envoyé donc pas de possibilité de distinguer un prerender d'une requête classique.

Chrome prerender

Un petit site de test a été mis au point sur http://prerender-test.appspot.com/ pour détecter l'activation (ou non) de cette fonctionnalité.

Il faut retenir qu'on peut aussi injecter ce type de balise avec JavaScript, de préférence dans la section <head>, c'est alors la dernière présente qui prendra le pas sur les autres.

Le: 24 07 2013 à 15:30 Auteur: Raphael

Alsacréations est fier de vous annoncer la naissance de Schnaps.it, notre nouvel outil de génération de code HTML / CSS !

Schnaps.it

Combinaison de plusieurs outils existants (KNACSS,  Schnapsum et Squelettor), Schnaps.it offre une palette de fonctionnalités lorsque vous débutez un nouveau projet web :

  • il permet de construire un squelette HTML vide très rapidement
  • il offre la possibilité de concevoir des gabarits de mise en page simple (une, deux, trois colonnes, hauteurs identiques, etc.) basés sur le mini framework KNACSS
  • il propose du faux-texte "Lorem Ipsum" en version alsacienne provenant de Schnapsum.

Le générateur de gabarits permet d'affiner certains réglages visuels des différents éléments (largeur, marges internes, marges externes, alignement de texte, etc.).

Une fois vos réglages effectués, il ne vous reste plus qu'à récupérer l'ensemble des fichiers en un clic !

générateur HTML

Un grand merci à Laetitia Bonanni, stagiaire dans l'agence Alsacréations pour ce joli travail réalisé tant du point de vue graphique que technique !

Le: 16 07 2013 à 11:00 Auteur: Raphael

C'est quoi l'accélération matérielle ?

flash

Comme le dit fort à propos Wikipédia : L'accélération matérielle consiste à confier une fonction spécifique effectuée par le processeur à un circuit intégré dédié qui effectuera cette fonction de façon plus efficace.

Dans le monde du Web cette possibilité concernera généralement les animations, et reposera sur la présence de deux éléments essentiels :

  • Le processeur : CPU (Central Processing Unit)
  • La carte graphique : GPU (Graphic Processing Unit)

Quel intérêt pour nos pages web ?

Certaines propriétés CSS affectent directement ou indirectement la taille de la boîte d'un élément : width, height, mais aussi margin, padding, border, top, right, bottom, left, etc.

Lorsque l'on modifie l'une de ces valeurs via CSS, le navigateur se voit contraint de recalculer la boîte ainsi que celles qui l'entourent et de "repeindre" la page (repaint).

Ce comportement est généralement insignifiant… sauf en cas de transition ou d'animation CSS : le navigateur, via le processeur, doit alors recalculer tous les éléments à chaque étape-clé de la transition !

La conséquence de cet effort du processeur se traduit par des effets de ralentissements et des saccades qui peuvent devenir très gênantes sur des périphériques de faible puissance, et en particulier sur des tablettes et smartphones.

Lors de vos animations CSS, pensez dans un premier temps à éviter les propriétés de "boîte" (citées précédemment) et remplacez-les avantageusement par des équivalents beaucoup plus performants (mais parfois moins compatibles) telles que les transformations : translations, rotations, déformations.

Et quand ce n'est pas possible,… il sera alors grand temps d'activer l'accélération matérielle via CSS, et le gain en fluidité sera immédiat et perceptible !

Activer l'accélération matérielle (AM) en CSS ?

limite 50 km/h

Appliquer une transformation CSS force un élément à s'afficher dans un "calque" indépendant du reste des éléments, permettant alors au navigateur de le traiter différemment.

L'une des possibilités offertes est alors de basculer tous les traitements et calculs de cet élément du côté de la carte graphique (GPU), et non plus du processeur (CPU). Bref, on active l'accélération matérielle.

Une transformation CSS "classique" (translate, rotate, skew, scale, matrix) ne suffit pas à activer l'accélération matérielle, il est nécessaire que cette transformation passe via l'axe de la pronfondeur (axe Z). En clair, il faut opérer une transformation 3D.

Voici une liste de déclarations CSS 3D permettant d'activer l'accélération matérielle sans altérer l'affichage ou la position de l'élément :

  • transform: translateZ(0);
  • transform: translate3d(0,0,0);
  • perspective: 1000; backface-visibility: hidden;

Les propriétés de transformations 3D sont plutôt bien supportées par les navigateurs, mais dans tous les cas, n'oubliez pas d'ajouter les préfixes constructeurs de rigueur (-webkit-, -moz-, -ms-, -o-) nécessaires tant que la spécification W3C du module des transformations 3D n'est pas finalisée.

Notez également que certains filtres CSS (CSS3 filters, actuellement à l'état de brouillon), WebGL, la vidéo et l'élément HTML5 <canvas> contribuent également à l'activation de la carte graphique.

Certains navigateurs permettent d'afficher les informations de la carte graphique et notamment si l'accélération est possible. Par exemple dans Firefox, la commande est  about:support, et dans Chrome la syntaxe est chrome://gpu :

GPU

Un exemple concret ?

Pour mieux comprendre la mise en pratique de l'accélération matérielle, je vous propose un court exemple concret. Le but est de faire apparaître un menu de navigation en transition lors d'un événement :

nav {
	transform: translate3d(-100%,0,0); /* activation de l'AM */
	transition: transform .4s;
}
nav.open {
	transform: translate3d(0,0,0);
}

Variante (plus compatible si les transformations 3D ne sont pas supportées) :

nav {
	position: absolute;
		left: -100%;
	transform: translate3d(0,0,0);  /* activation de l'AM */
	transition: left .4s;
}
nav.open {
	left: 0;
}

Les snippets de navigation responsive sur la page goetter.fr/nav activent tant que faire se peut l'accélération matérielle. Je vous invite à les décortiquer et vous les approprier.

Pratique aussi pour les filtres CSS

speed

Les filtres CSS, actuellement en brouillon dans les spécifications, offrent de nouvelles possibilités graphiques fort intéressantes : flou, noir et blanc, sépia, contraste, luminosité, etc.

Cependant, à l'instar des animations, certains filtres CSS tels que blur (flou) posent des problèmes de lenteur sur mobiles.

Dans ce cas, activer l'accélération matérielle vous sera également d'une grande utilité.

Et aussi pour le lissage des polices !

Le lissage des polices laisse souvent à désirer sur Chrome Windows, je ne vous l'apprends sans doute pas. Sachez que dans ce domaine aussi l'activation de l'accélération matérielle peut faire des miracles.

Prenez deux caractères agrandis et tournés. Dans le premier cas, opérez une rotation simple à l'aide d'une transformation classique. Dans le second cas, ajoutez une transformation CSS 3D afin de solliciter la carte graphique. Vous serez bluffés par le résultat (à voir sur CodePen) :

span {
	display: inline-block;
	-webkit-transform: rotate(60deg);
}
span+span {
	-webkit-transform: rotate(60deg) translate3d(0,0,0);
}

Accélération Materielle et lissage de police

Conclusion

Activer l'accélération matérielle favorise la fluidité des animations CSS, mais provoque également d'autres effets bénéfiques pour les périphériques dont le processeur est parfois à la traîne.

Sachez en profiter sans toutefois en abuser : les cartes graphiques de nos anciens mobiles ne sont pas non plus des foudres de guerre et pourraient facilement pâtir d'un excès de zèle dans vos choix d'activation matérielle.

Le: 07 07 2013 à 17:00 Auteur: dew

Deux attributs HTML permettent de modifier le comportement des balises <script> et plus particulièrement pour le chargement des ressources JavaScript :

  • async : charger/exécuter les scripts de façon asynchrone.
  • defer : différer l'exécution à la fin du chargement du document.

Ils sont souvent confondus avec pourtant des conséquences différentes. À l'heure où les performances sont surveillées de plus en plus près par les robots d'indexation, et les temps de chargement scrutés pour le confort des utilisateurs, leur usage est le bienvenu.

Ces attributs sont reconnus par tous les navigateurs modernes actuels : Firefox 3.6+, Chrome, Safari, à partir d'Internet Explorer 10 et bientôt Opera. Y compris dans les versions mobiles. Si un moteur ne comprend pas l'un ou l'autre, ceci ne se révélera pas bloquant pour l'interprétation du document, les performances resteront simplement "non optimisées".

Attributs async et defer, effets communs

Le but de ces deux attributs, décrits en détails ci-après, est principalement de charger et lancer l'interprétation de code JavaScript sans bloquer le rendu HTML (son affichage à l'écran). Ils ne concernent en général que des interprétations de codes situés dans des fichiers externes (lorsque l'attribut src est utilisé) et viennent assouplir la pratique communément admise de placer - dans la mesure du possible - les balises <script> à la fin du document juste avant la fermeture de </body>.

Le goulot

Cette dernière recommandation provient d'un comportement que les navigateurs ne peuvent éviter : par défaut (et pour simplifier), toute balise <script> rencontrée met en attente le moteur HTML/CSS car le navigateur ne sait pas si le code JavaScript va contenir des instructions spécifiques à exécuter immédiatement qui pourront avoir une conséquence importante sur... le code HTML/CSS lui-même, notamment avec la fonction document.write(). Il va donc falloir effectuer des requêtes HTTP vers le serveur pour chaque fichier JavaScript externe, attendre les réponses, recueillir le code et l'exécuter. Ces actions prennent souvent plusieurs dizaines de millisecondes. Avec plusieurs éléments <script> comme on le voit souvent dans le code source des pages et applications web, le ralentissement du chargement en est multiplié d'autant.

Exemple brut

Pour examiner les cas de figure pouvant se présenter, partons d'une page-type dans laquelle se situent des balises <script> dans l'en-tête, le corps et la fin du document. L'une d'entre elles fait appel à un fichier script-lent.js qui comme son nom l'indique met volontairement un peu plus d'une seconde à être délivré par le serveur.

<!doctype html>
<html>
<head>
<title>Test JS</title>
<script>if(typeof console!='undefined') console.time('Timing');</script>
<script src="script-lent.js"></script>
</head>
<body>

<p>Script dans <head> et avant </body></p>
<script>if(typeof console!='undefined') console.debug('Affichage du body HTML');</script>

<script src="script.js"></script>
<script src="script2.js"></script>
<script>if(typeof console!='undefined') console.timeEnd('Timing');</script>
</body>
</html>

Dans ce cas de figure, nous observons le comportement suivant :

Du côté réseau :

Verdict

  • Le premier fichier (script-lent.js) ralentit tous les autres, il met plus d'une seconde à être chargé et interprété.
  • Le téléchargement des autres scripts démarre en même temps.
  • Mais il faut tout de même attendre l'obtention de script-lent.js pour que le document soit affiché (ce qui correspond à la barre verticale bleue représentant l'événement DOMContentLoaded)
  • Délai final avant affichage : 1.25 seconde
  • Le chronomètre nommé Timing placé à la fin du contenu de la page mesure un temps total de 1.065 seconde, ce qui veut dire que son exécution prend place après toutes les autres balises <script>

L'attribut defer

Antérieur à la vague HTML5, l'attribut defer existait déjà dans les "anciennes" versions d'Internet Explorer. Il signifie que le navigateur peut charger le(s) script(s) en parallèle, sans stopper le rendu de la page HTML. Contrairement à async, l'ordre d'exécution des scripts est préservé, en fonction de leur apparition dans le code source HTML. Il est par ailleurs reporté à la fin du parsing du DOM (avant l'événement DOMContentLoaded). De nos jours, cet attribut présente moins d'intérêt car les navigateurs disposent par défaut de techniques internes pour télécharger les ressources en parallèle sans nécessairement attendre les autres.

<script src="code.js" defer></script>

Reprenons le premier code en ajoutant l'attribut defer.

Exemple avec defer

<!doctype html>
<html>
<head>
<title>Test JS</title>
<script>if(typeof console!='undefined') console.time('Timing');</script>
<script src="script-lent.js" defer></script>
</head>
<body>

<p>Script dans <head> et avant </body></p>
<script>if(typeof console!='undefined') console.debug('Affichage du body HTML');</script>

<script src="script.js" defer></script>
<script src="script2.js" defer></script>
<script>if(typeof console!='undefined') console.timeEnd('Timing');</script>
</body>
</html>

Dans ce cas de figure, nous observons le comportement suivant :

Côté réseau :

Verdict :

  • Peu ou pas de différence par rapport à l'exemple précédent, car le navigateur charge déjà en parallèle les fichiers.
  • Il faut tout de même attendre l'exécution du premier (script-lent.js) pour voir du contenu apparaître sur la page puisque le moteur a pour règle de conserver l'ordre d'exécution en fonction de l'apparition des balises <script> dans le code source.
  • Délai final avant affichage : 1.20 seconde
  • En revanche, le chronomètre Timing est beaucoup plus court (quelques ms), toutes les autres balises <script> ayant été virtuellement déplacées après ce dernier, à la fin du document avec defer, il prend donc place avant leur interprétation.

L'attribut async

Nouveau venu dans HTML5, async signifie que le script pourra être exécuté de façon asynchrone, dès qu'il sera disponible (téléchargé). Cela signifie aussi que le navigateur n'attendra pas de suivre un ordre particulier si plusieurs balises <script> sont présentes, et ne bloquera pas le chargement du reste des ressources, notamment la page HTML. L'exécution aura lieu avant l'événement load lancé sur window et ne sera valable que pour les scripts externes au document, c'est-à-dire ceux dont l'attribut src mentionne l'adresse.

<script src="code.js" async></script>

Ce comportement est bien pratique pour gagner en temps de chargement, il faut cependant l'utiliser avec prudence : si l'ordre n'est pas respecté, un fichier exécuté de façon asynchrone ne pourra attendre le chargement d'un précédent, par exemple s'il en utilise des fonctions voire un framework. Il ne faudra pas non plus compter appeler document.write() pour écrire dans le document HTML puisqu'il sera impossible de savoir à quel moment les actions seront déclenchées.

En résumé, n'écrivez pas ça :

<!-- Attention le code ci-dessous est un contre-exemple, ne PAS utiliser -->
<script src="jquery.js" async></script>
<script src="autre_script_utilisant_jquery.js" async></script>

Reprenons le premier test en ajoutant l'attribut.

Exemple avec async

<!doctype html>
<html>
<head>
<title>Test JS</title>
<script>if(typeof console!='undefined') console.time('Timing');</script>
<script src="script-lent.js" async></script>
</head>
<body>

<p>Script dans <head> et avant </body></p>
<script>if(typeof console!='undefined') console.debug('Affichage du body HTML');</script>

<script src="script.js" async></script>
<script src="script2.js" async></script>
<script>if(typeof console!='undefined') console.timeEnd('Timing');</script>
</body>
</html>

Dans ce cas de figure, nous observons le comportement suivant :

Côté réseau :

Verdict

  • L'affichage peut se produire dès la réception du code HTML (voir la barre verticale bleue correpsondant à l'événement DOMContentLoaded)
  • Le téléchargement des autres scripts reste semblable
  • Mais l'ordre n'est pas préservé : chaque script est exécuté dès qu'il est disponible, et script-lent.js est le dernier à survenir.
  • Délai final avant affichage : 0.16 seconde soit 8 fois moins qu'avant
  • Le chronomètre nommé Timing placé à la fin du contenu de la page est exécuté rapidement, juste après l'affichage HTML, sans attendre les autres balises <script>

Notes complémentaires

Selon la nature des scripts à exécuter, les deux attributs peuvent être utilisés ensemble.

En général, les scripts créés dynamiquement (c'est-à-dire par des instructions JavaScript elles-mêmes et non par des balises <script>), se voient automatiquement affublés de l'attribut/comportement async puisqu'il ne sont pas liés à un ordre logique déclaré dans le DOM.

Astuce : Les attributs async et defer pour