Optimiser parfaitement WordPress pour les mobiles avec AMP HTML
Le projet AMP (Accelerated Mobile Pages) est une librairie HTML open source qui permet de considérablement accélérer les pages web sur les supports mobiles. Les pages en AMP HTML peuvent être chargées jusqu'à 4 fois plus rapidement que les pages web classiques, tout cela en chargeant jusqu'à 8 fois moins de données qu'habituellement.
Soutenu notamment par Google, Twitter, Pinterest et Linkedin, AMP HTML risque de devenir un phénomène majeur sur mobile en 2016, à tel point que Google a déjà évoqué un boost SEO et une indexation spécifique des pages en AMP HTML (sans oublier le label "fast" qui pourrait accompagner ces pages optimisées dans les SERP).
Comme je suis un passionné de WordPress et que le firme soutient AMP également, je me suis penché sur la question d'un passage de WordPress vers AMP HTML, notamment pour le WPTech qui se tenait à Nantes le 5 décembre 2015. Je tiens donc à vous fournir quelques premières possibilités pour optimiser votre site WordPress pour les mobiles.
Retenons qu'il nous faut plusieurs étapes pour que le système fonctionne :
- Installer le plugin WordPress AMP. Si ce dernier est disponible dans les extensions du CMS (https://wordpress.org/plugins/amp/), il est conseillé de le télécharger via la page GitHub qui lui est dédiée, la version étant mise à jour et plus complète (https://github.com/Automattic/amp-wp).
- Détecter les supports mobiles. Cela peut se faire par user-agent (ce sera le cas ici) ou par analyse de la résolution du support (un peu comme en responsive web design en CSS).
- Optimiser le passage vers les pages en version AMP HTML. Ici, je vais présenter ce que j'ai fait pour ce blog, à savoir créer un bouton pour laisser le choix à l'utilisateur (car toutes les pages ne fonctionnent pas en AMP HTML, il faut le savoir). Mais il existe une alternative qui force le chargement des pages AMP HTML sur les mobiles si cela vous sied davantage.
- Modifier l'ensemble des URL WordPress avec le suffixe "AMP". Selon le type de permaliens que vous utilisez, le suffixe peut prendre la forme de "?amp=1" ou "/amp/" (le dernier slash est optionnel en fait). Le problème du plugin, c'est qu'il ne modifie pas automatiquement les URL WordPress utiles (il ne faut pas toutes les changer puisque des pages ne fonctionnent pas avec AMP HTML), ce qui oblige les utilisateurs à retomber dans la version classique du site dès qu'ils cliquent sur un lien. Comme je n'ai pas ça (ce n'est pas ergonomique), je vous proposerai une solution en Javascript natif pour contrecarrer ce problème.
- Adapter votre thème en AMP HTML. Le plugin créé un thème simple et rapide à charger, mais qui casse complètement votre thème originel, retirant même le menu (voir capture ci-dessous). Les concepteurs planchent actuellement sur des solutions mais rien ne dit qu'ils trouveront une solution idéale. Je vais vous montrer comment j'ai fait sur ce blog pour obtenir le même thème avec ou sans AMP HTML en partant du plugin de WordPress.
Étape n°1
Installez le plugin AMP HTML via GitHub idéalement, puis créez un fichier Javascript (appelé ici detectmobilebrowserAMP.js) contenant une première fonction de détection des mobiles.
Cette fonction est basée sur les codes proposés par le site detectmobilebrowsers.com, mais réécrite pour retourner un booléen (true/false).
function isMobile(a){ if(/(android|bbd+|meego).+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(a.substr(0,4))) { return true; } else { return false; } }
Étape n°2
Créez un système pour passer vers les pages en AMP HTML.
Ici, j’ai surtout développé un bouton qui permet de switcher entre la version responsive design et la version en AMP HTML. Le code correspondant sera présenté à l’étape suivante, avec une variante possible (chargement direct de la page AMP).
Étape n°3
Ajoutez le code suivant pour créez un switch entre la version mobile classique et la version AMP HTML.
N.B. : la variante permet de faire une redirection automatique vers les pages mobiles, mais il faut bien faire attention à ne pas le faire quand les pages ne fonctionnement pas avec AMP (non codé ici…).
if(isMobile(navigator.userAgent||navigator.vendor||window.opera)) { // Créer un lien pour la version AMP HTML var div = document.createElement('div'); div.className = "amp-link"; // Ajout d'une classe CSS au bouton // Vérification de la présence du suffixe "/amp" dans l'URL // 1. Si le suffixe n'est pas présent, proposez le bouton vers AMP // 2. Dans le cas inverse, proposez un bouton vers la version classique if(document.URL.lastIndexOf("/amp") === -1) { urlAMP = document.URL; div.innerHTML = '<a href="'+urlAMP+'amp/">Version AMP (rapide)</a>'; } else { urlAMP = document.URL.substr(0, parseInt(document.URL.indexOf("/amp"))); div.innerHTML = '<a href="'+urlAMP+'">Version classique</a>'; } // Ajout du lien dans la zone désirée // var cible = document.getElementById('header'); var cible = document.getElementById('search-social'); cible.parentNode.insertBefore(div, cible); } // Variante pour faire redirection automatique directe if(isMobile(navigator.userAgent||navigator.vendor||window.opera)) { // Pensez à rajouter du code pour bloquer les pages non compatibles avec AMP window.location= document.URL+'amp/'; }
Étape n°4
Modifiez automatiquement toutes les URL compatibles avec AMP lorsque vous êtes dans la version optimisée.
Ici, vous verrez que j’ai dû traiter le cas des ancres nommées pointant vers les commentaires, inscrits par défaut par la fonction comments_popup_link() de WordPress notamment.
N.B. : par défaut, le plugin WordPress ne fait pas ce changement automatique, donc chaque clic sur une URL renvoie vers la version classique du site, il faut donc passer outre ce défaut actuel.
// Automatiquement ajouter le suffixe "/amp/" à tous les liens du site (sauf externes !) if(document.URL.lastIndexOf("/amp") != -1) { for(var i = 0; i < document.links.length; i++){ // Vérifie automatiquement s'il y a un slash à la fin de l'URL if((document.links[i].href.lastIndexOf('/') - document.links[i].href.length + 1) === 0) { var ampSuffixe = "amp/"; } else { var ampSuffixe = "/amp/"; } // Récupérer tous les liens du même domaine et ajouter le suffixe quand il le faut if(document.links[i].href.indexOf(document.location.origin) != -1) { // Option 1 : conserver uniquement les URL qui doivent porter le suffixe "/amp/" var regexPagePost = new RegExp("([0-9]+)/([0-9]+)/"); if(regexPagePost.test(document.links[i].href)) { // Nettoyer le lien avec #respond (commentaires) var regexCommentaire = new RegExp("(#respond)"); if(regexCommentaire.test(document.links[i].href)) { // Ajout du suffixe AMP pour l'ancre nommée vers les commentaires document.links[i].href = document.links[i].href.replace(/#respond/i, "amp/#respond"); } else { if(urlAMP != document.links[i].href) { // Ajout du suffixe AMP automatiquement document.links[i].href = document.links[i].href+ampSuffixe; } } } /* // Option 2 : exclusion des liens qui ne doivent pas avoir le suffixe (à personnaliser selon le site) if(document.links[i].href.indexOf("/feed") == -1 && document.links[i].href.indexOf("#respond") == -1) { // Ajout du suffixe AMP automatiquement document.links[i].href = document.links[i].href+ampSuffixe; } */ } } }
Étape n°5
Adaptez votre thème WordPress en AMP HTML. Il convient de modifier le thème par défaut qui est bien trop simpliste et limité, mais le plugin ne le permet pas par défaut, il faut donc développer le système manuellement.
Voici la technique que j’ai employée :
- modification du fichier template.php du plugin AMP de WordPress (voir code).
- ajout d’un dossier « amp » (ou « template » si vous préférez) dans le plugin avec une copie des pages à modifier. Cela dépend de votre thème mais en général, il s’agit de header.php, footer.php, single.php, page.php, category.php, etc.
- modification des fichiers pour modifier le code et l’adapter à AMP HTML (changer les balises <img/> fixes en <amp-img>…</amp-img>, etc.). L’étape suivante vous montrera juste qu’il faut conserver le début de l’entête spécifique à AMP.
Ne déplacez que les fichiers nécessaires, il n’est pas utile de recopier le fichier style.css par exemple, ni les pages inadaptées en AMP HTML !
<?php include( dirname( __FILE__ ) . '/amp/header.php' ); ?> <?php if(is_home()) { include( dirname( __FILE__ ) . '/amp/index.php' ); } elseif(is_category()) { include( dirname( __FILE__ ) . '/amp/category.php' ); } elseif(is_single()) { include( dirname( __FILE__ ) . '/amp/single.php' ); } elseif (is_page()) { include( dirname( __FILE__ ) . '/amp/page.php' ); } ?> <?php include( dirname( __FILE__ ) . '/amp/footer.php' ); ?>
Étape n°6
Pensez à conserver les lignes importantes du header.php, pour que le projet AMP soit bien activé dans les pages.
Je vous présente ici une version « light » du header.php original du plugin contenant les lignes à absolument conserver (en gras).
<!doctype html> <html amp> <head> <title><?php echo esc_html( $amp_post->get_title() ); ?> | <?php echo esc_html( get_bloginfo( 'name' ) ); ?></title> <meta charset="utf-8"> <link rel="canonical" href="<?php echo esc_url( $amp_post->get_canonical_url() ); ?>" /> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui"> <link href='https://fonts.googleapis.com/css?family=Merriweather|Open+Sans:400,700,400italic,700italic' rel='stylesheet'> <?php foreach ( $amp_post->get_scripts() as $element => $script ) : ?> <script custom-element="<?php echo esc_attr( $element ); ?>" src="<?php echo esc_url( $script ); ?>" async></script> <?php endforeach; ?> <script src="https://cdn.ampproject.org/v0.js" async <?php echo defined( 'AMP_DEV_MODE' ) && AMP_DEV_MODE ? 'development' : ''; ?>></script> <script type="application/ld+json"><?php echo json_encode( $amp_post->get_metadata() ); ?></script> <?php do_action( 'amp_head', $amp_post ); ?> <style>body {opacity: 0}</style><noscript><style>body {opacity: 1}</style></noscript> </head>
Conclusion
Si vous respectez toutes ces étapes, je ne doute pas que vous pourrez passer votre site WordPress en AMP HTML. Quoi qu’il en soit, je ne vois pas comment le plugin pourrait nous permettre de ne pas mettre les mains dans le code, il y aura forcément des morceaux du thème à modifier manuellement pour que tout soit bien compatible.
Vous pouvez téléchargez ici le fichier detectmobilebrowserAMP.min.js (version compressée) présenté dans ce tutoriel si nécessaire (avec toutes les fonctions du guide), cela vous évitera de tout recopier manuellement.
Ce tutoriel n’est pas parfait à 100% car il dépend de votre thème (et quand je vois certains thèmes achetés, j’ai peur…) et de vos capacités techniques pour adapter le template en AMP HTML. Qui plus est, le fait d’utiliser du Javascript peut être parfois contraignant, certains utilisateurs bloquent le langage par défaut dans les navigateurs. C’est pourquoi il est important d’avoir toujours une version responsive design de secours en amont…
Sachez que dans cet exemple, je n’ai pas traité les publicités Adsense (ou autres régies compatibles) qui utilisent le couple de balises <amp-ad>…</amp-ad> ni le cas traité récemment par Google pour Google Analytics, dont l’astuce est d’utiliser les balises <amp-pixel>…</amp-pixel>. Il faudrait donc encore aller plus loin dans le développement spécifique pour faire de l’AMP parfait pour WordPress.
Il est probable que je fasse un autre tutoriel sur AMP HTML via PHP prochainement, avec des fonctions spécifiques (dont certaines sont déjà créées) pour passer tous types de sites web vers ces versions optimisées. Le plus long est de développer les fonctions pour chaque type de balise, et comme je ne les utilise pas toutes dans mes propres sites web, je risque d’en oublier au passage…