L’amélioration progressive est toujours importante

Par Jake Archibald

À l'heure des applications web et de l'omniprésence de JavaScript, Jake Archibald, relation développeurs chez Google, nous rappelle de continuer à utiliser une démarche d'amélioration progressive.

Il y a près de 5 ans je pensais que l’amélioration progressive était un combat définitivement gagné. Mais dernièrement j’ai vu les commentaires de l’article « Arrêtez donc avec JavaScript » de Nicholas Zakas ressusciter de vieux arguments, et même en faire naître de nouveaux. Bien, j’ai ma tenue de combat et je suis prêt à en découdre avec les grandes gueules.

Il ne s’agit pas des utilisateurs sans JS

Si vous désactivez JavaScript, vous allez passer un sale quart d’heure sur le Web. Si vous retirez le volant de votre voiture vous allez passer un sale moment dans les virages. Mon conseil : laissez le volant à sa place.

L’amélioration progressive n’a jamais été destinée aux utilisateurs qui ont désactivé JavaScript, ou du moins de mon point de vue.

Ascenseurs contre escalators

Christian Heilmann a reformulé une observation de Mitch Hedberg pour l’appliquer à l’amélioration progressive. En gros, si un ascenseur tombe en panne, il devient inutile. Si un escalator tombe en panne, il se transforme en escalier. Nous devrions construire des escalators, pas des ascenseurs.

Compte tenu de la diversité des agents utilisateurs (User Agents), le plantage de votre JavaScript n’est pas un cas à la marge. Ce sera parfois de la faute du navigateur, parfois de la vôtre. Par exemple, il y a quelques mois, le JavaScript de la page de téléchargement de Chrome buguait. Savez-vous ce qui se passait quand on cliquait sur le bouton « Télécharger Chrome » ? Rien. Une pincée d’amélioration progressive aurait permis de continuer à télécharger Chrome en attendant la correction du problème.

Réduire vos besoins de tests dans les vieux navigateurs

Il y a quelques années, je travaillais sur un site intranet pour une grosse entreprise. Je l’avais construit avec de l’amélioration progressive par habitude. Les utilisateurs étaient pour la plupart sur IE7, c’était un environnement étroitement contrôlé.

Puis, au dernier moment, le client demanda que le site fonctionne sur les Blackberry. Et pas sur les versions modernes avec WebKit, mais sur le vieux navigateur Blackberry, qui était encore utilisé par certains. Le site était un désastre sur ce dernier.

Toutefois, le vieux navigateur gérait plutôt correctement HTML et CSS, c’est uniquement quand il était question de JS qu’il se transformait en générateur de bugs aléatoires.

Un peu de détection d’agent utilisateur (hum…) plus tard, nous n’envoyions plus JS aux Blackberry. Cela régla instantanément 90% de nos problèmes. Le reste ne concernait que quelques ajustements mineurs de CSS. Ceci n’a été possible que parce que le site fonctionnait sans JS. Bien entendu, il y avait des rafraîchissements de pages complètes que les navigateurs plus récents faisaient plus vite avec de l’Ajax, et quelques jolies transitions manquaient à l’appel, mais cela fonctionnait.

Nous avons poussé cette idée plus loin pour la version mobile de Lanyrd où une simple détection de capacité était utilisée pour décider si les scripts devaient être chargés. Nous avons fait bien attention à n’utiliser JavaScript que pour ce qui ne pouvait être géré par AppCache.

La BBC appelle ce test de fonctionnalités « couper la moutarde ». Rendez-vous service, réservez votre JS aux navigateurs les plus modernes, et vous n’aurez plus qu’à servir aux vieux navigateurs du HTML et du CSS.

Il est important de faire cela au moment du chargement des scripts plutôt que juste avant leur exécution. Non seulement vous éviterez le chargement du JS dans les navigateurs qui n’en ont pas besoin, mais vous économiserez aussi en parsing [NDLR : Décomposition analytique en français]. Sur de vieux mobiles bancals, tel le Blackberry, le parsing peut prendre bien plus de temps que le téléchargement, et l’interface se retrouve bloquée pendant ce temps-là.

Réduire vos besoins de tests en général

Quand je travaille côté serveur, il faut que cela fonctionne en Django 1.5.1 fonctionnant sur Python 2.7.3, servi via Nginx 1.1.19, etc. Je contrôle l’architecture, si je change l’une des dépendances je peux tester le tout avant de déployer.

Le code qui tourne côté client demande plus de tests étant donné la diversité des fournisseurs et versions de navigateurs. À moins que votre architecture serveur ne change constamment, c’est plus facile d’avoir la plupart de votre logique côté serveur.

Être plus rapide

JavaScript est plus puissant que HTML et CSS, tout comme une Formule 1 est plus puissante qu’un vélo. Mais une Formule 1 a une procédure de démarrage complexe et requiert une équipe entière pour se lancer. Si les deux font la course, c’est le vélo qui partira le premier, et si la distance à parcourir est suffisamment courte, c’est lui qui gagnera.

Voici comment la plupart des pages se chargent :

  1. téléchargement du HTML ;
  2. téléchargement du CSS ;
  3. CSS télécharge des ressources supplémentaires ;
  4. téléchargement du JS ;
  5. exécution du JS ;
  6. JS télécharge des ressources supplémentaires ;
  7. JS met à jour le DOM.

C’est l’ordre dans lequel cela se passe généralement, les étapes 1 à 4 pouvant être effectuées en parallèle dans une certaine mesure.

Dans une page améliorée progressivement, l’étape 2 bloque le rendu, mais à part ça le HTML peut être parsé et rendu par fragments au fur et à mesure du téléchargement. Tout cela en considérant que vos scripts sont chargés de manière asynchrone ou sont appelés au bas du document, ce qui devrait être le cas (à propos du chargement de scripts). Dans ce cas, l’étape 6 n’est sans doute pas nécessaire et l’étape 7 est mineure.

De plus, la plupart des navigateurs modernes vont tenter d’anticiper sur les pages que vous pourriez ouvrir, et y chercher les ressources nécessaires, donc il y a des chances que le navigateur ait déjà démarré le téléchargement des CSS et JS.

Dans une page intégralement gérée en JS, telle que <body></body>, le premier rendu est bloqué par les 7 étapes. Bien sûr, votre téléchargement HTML est très petit, mais votre JS ne l’est pas, et vous n’obtenez aucun rendu progressif. Si votre JS doit télécharger d’autres ressources, cela bloque aussi le rendu, et ne peut pas être détecté par le parser qui tente de démarrer dès que possible les téléchargements de CSS et JS.

Les pages dépendant de JS qui ne sont pas réduites à <body></body> peuvent réussir à démarrer le rendu plus tôt, mais les interactions ne sont pas possibles tant que les 7 étapes ne sont pas finalisées.

Alors oui, si la course est un peu plus longue, c’est la Formule 1 qui va gagner et c’est pour cela que vous faites de l’amélioration progressive : vous démarrez en tête sur votre vélo, et alors que la Formule 1 s’apprête à vous dépasser, vous bondissez de votre selle, faites un superbe salto arrière dans les airs, vous installez aux commandes de la Formule 1, puis appuyez sur le champignon.

Twitter est un très bon exemple de tout ceci : leur site tout-JS était horriblement lent et réagissait maladroitement. Ils sont en train de résoudre ces problèmes en optant pour l’amélioration progressive.

De même quand Airbnb a amélioré ses performances en utilisant HTML comme format de réponse (et tenté au passage de présenter cela comme une innovation), les fans de l’amélioration progressive se sont tous dit : « on vous l’avait bien dit ».

Et ne me parlez pas de blogger.com.

Ça ne double pas votre temps de travail

On peut avoir l’impression que l’amélioration progressive contraint à tout construire côté serveur puis à tout reconstruire, de la même manière, côté client. C’est rarement le cas. Appuyez-vous sur le serveur autant que possible.

Si vous voulez mettre à jour dynamiquement une partie de la page, c’est super si c’est plus rapide, mais avez-vous besoin de templates côté client ? Est-ce que le serveur ne peut pas simplement vous envoyer la partie de HTML nécessaire ? C’est souvent le cas. Souvenez-vous, HTML est un format de données sémantique tout comme JSON, et si vous devez simplement convertir du JSON vers du HTML, autant le faire côté serveur.

Si vous avez besoin de templates côté client, préférez un format utilisable aussi côté serveur, comme Mustache. Envisagez également de compiler les templates sous forme de fonctions JavaScript sur le serveur et servez-les ainsi, cela évitera à chaque client d’avoir à faire le parsing et la compilation.

Travailler avec le navigateur, pas contre lui

Le site web mobile de Lanyrd est construit avec de l’amélioration progressive, mais nous avons utilisé JavaScript pour gérer toute la navigation de page en page (de la même manière que nous utiliserions Ajax pour ramener de nouveaux contenus). Nous avons fait cela dans dans le but de contourner les limitations de AppCache, et cela a eu un coût.

Pour commencer, vous cliquez sur un lien, dont JS modifie le contenu. À ce moment là, l’URL ne reflète plus le contenu. Mais tout va bien, nous avons history.pushState(). Ensuite l’utilisateur clique sur le bouton de retour, nous détectons le changement d’URL et remettons en place le contenu précédent. Toutefois, cela ne semble pas très naturel pour l’utilisateur qui est renvoyé en haut de page, alors qu’il s’attend à se retrouver à l’endroit où il était précédemment. Bien, nous allons donc enregistrer les positions de scroll avant de changer le contenu, et travailler sur les conditions pour lesquelles le positionnement doit être rétablit.

Plus vous prenez le pas sur le navigateur, plus les comportements attendus à reproduire en JavaScript seront complexes. Et si différents navigateurs font différentes choses, vous devez alors choisir un comportement qui semblera étrange aux utilisateurs qui n’y sont pas habitués.

« Application » n’est pas une excuse

« Ouais, mais je construis une application web, pas un site. » J’entends cela tout le temps et ce n’est pas une excuse. Je vous mets au défi de définir les différences entre une application et un site web qui ne soit pas une vague liste de bonnes pratiques que les « applications » sont pour des raisons qui m’échappent autorisées à ignorer. Jeremy Keith explique cela brillamment.

Par exemple, est-ce que Wikipedia est une application ? Et quand j’édite un article ? Et quand je recherche un article ?

Que vous appeliez votre page web un « site », une « application », un « micro site », ou que sais-je encore, elle ne doit pas faire l’impasse sur l’accessibilité, les performances, le support navigateur, etc.

Si vous vous cherchez une excuse pour vous abstenir de passer à l’amélioration progressive, il vous faudra en trouver une meilleure.

Il y a, bien sûr, des exceptions

…mais elles doivent rester des exceptions. SpriteCow, Jank Invaders et Request Quest dépendent tous de JS.

SpriteCow pourrait être réalisé côté serveur, mais c’est un des rares cas où le client peut totalement surclasser le serveur en raison des données d’images à transférer.

Jank Invaders est simplement une démonstration d’une possibilité JavaScript, et comme beaucoup de jeux n’a tout simplement pas de solution de repli côté serveur.

Request Quest dépend de JavaScript car il est… euh… il doit traiter… bon ok, j’ai juste été fainéant. Ne faites pas ça !

Une des meilleures choses sur le Web est que l’on peut rivaliser avec les applications natives sans nécessiter de téléchargement préalable, sans procédure d’installation, et cela quel que soit l’âge des appareils. Faisons en sorte que cela reste ainsi.

NB : Emil Björklund a rédigé un article similaire qui mérite également d’être lu.

Fiche technique

À propos de l'auteur

Jake Archibald est chargé des relations développeurs chez Google pour Chrome.

Articles similaires

Voici la liste des dix articles les plus récents en rapport avec cet article :

JavaScript

Technique

© 2001-2016 Pompage Magazine et les auteurs originaux - Hébergé chez Nursit.com ! - RSS / ATOM - About this site