Le blog

Référencement : Comment améliorer la note de votre site sur Google Pagespeed

  • mardi 11 août 2015 à 16h45 | 2865 vues

Parmi les très nombreux critères pris en compte par l’algorithme de Google afin de définir la position d'un site internet sur sa page de recherche, deux nouveaux ont fait leur apparition début 2015, et non des moindres puisqu'il est question de la compatibilité mobile, ainsi que la vitesse de chargement des pages dans le navigateur web.

Il est donc de important de montrer patte blanche pour ne pas pâtir de résultats catastrophiques en terme de positionnement, et pour cela il va falloir mettre les mains dans le cambouis. Je ne vais pas traiter de la partie concernant la portabilité vers les terminaux mobile d'un site ici, car de multiples solutions et approches différentes existent en ce domaine, comme Bootstrap, Foundation, Skeleton, SkelJs, ou encore KnaCss, un framework css simple et léger élaboré par les développeurs d'Alsa-Créations, sans parler des nombreux thèmes ou plugins existants capables de se charger de cette tache pour la plupart des CMS du marché, pas besoin donc de réinventer la roue.

Je vais par contre m'attarder un peu sur l'autre partie, celle concernant la vitesse de chargement des pages, car à moins - la aussi - de posséder un Wordpress, Joomla, Opencart ou autre CMS offrant une forte communauté de développeurs qui proposent de nombreuses extensions pour optimiser votre site, il faut un peu se retrousser les manches et sortir la caisse à outils pour un site « fait-main » comme c'est le cas pour celui de Vision-design.fr.

Pour le suivi des résultats, j'ai utilisé les deux plus sérieux à mes yeux, l'outil Google PageSpeed Insights, et GTmetrix, un peu plus complet, mais vous pouvez également tester vos résultats sur woorank, qui n'est pas non plus avare en options, ou encore Pingdom, et il en existe plein d'autres...Pour la petite info, l'environnement serveur est sous apache (PHP donc), et sur serveur mutualisé (OVH).

Des chargements retardés

@ crédit image https://bulledev.com

Alors que les anciennes pratiques préconisaient de faire appel aux fichiers javascript et css entre les balises <head> et </head>, il est désormais répandu, du moins concernant les fichiers javascript, de les charger en dernier lieu, avant la fermeture de la balise </body>, mais cela ne suffit pas pour plaire à Google, qui préconise de déférer le chargement de ces fichiers, parfois un peu lourds, comme c'est le cas pour certaines librairies telles que jQuery ou encore Bootstrap. Il existe bien les attributs defer ou async que l'on peut ajouter, mais l'un comme l'autre ne produisent pas les résultats escomptés, et ne fonctionnent que pour les fichiers javascript.

Pour les fichiers css un peu volumineux qui bloquent l'affichage du contenu au-dessus de la ligne de flottaison (ex Bootstrap), l'astuce est relativement simple, elle consiste à diviser le fichier en deux parties, la première se voulant minimaliste et comportant les parties essentielles requises pour un affichage correct de la page, telles que le reset css, le système de grille et de boîtes, les couleurs de fond, les tailles de typographies, etc. Vous pourrez ensuite charger en fin de page, juste avant la balise </body> la seconde feuille de style comportant les reste des éléments lourds non vitaux, qui font appel aux polices de caractères, aux images de fond, etc. Il est important de noter que pour éviter un remontage de bretelles de la part du moteur de tests, il va falloir oublier les imports (@import url('style.css')).

La partie javascript n'est pas très compliquée, et consiste à retarder le chargement des fichiers, mais en les chargeant dans l'ordre voulu, car il est fréquent de voir des librairies dépendre d'autres. Voici le script que j'ai fait pour vision-design.fr, libre à vous de l'utiliser pour votre site si vous le souhaitez. Celui ci surveille le chargement de la page en prenant en compte les différents navigateurs, et appelle la fonction deferLoadingFile() une fois la page chargée. Dans cette fonction se trouve un tableau (scripts = []), dans lequel vous devez placer l'url des fichiers à appeler(javascript ou css) dans l'ordre désiré, qu'ils soient en local ou distants.

La fonction va appeler chaque fichier, puis vérifier quil soit chargé complètement avant d'appeler le suivant, ce qui vous évitera de constater des messages d'erreur javascript du genre « jQuery is not defined » dans la console


<script>
function deferLoadingFile() {
    var scripts = [
    "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js",
    "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js",
    "js/init.min.js"
    ];
    var loadeds = [];
    var add = function(key) {
        if(typeof(key) == "undefined"){ 
            key = 0;
        }
        if(loadeds.indexOf(key) == -1){
            next    = key + 1;
            src     = scripts[key];
            tag     = (src.indexOf(".css") !== -1)? "link" : "script";
            element = document.createElement(tag);
            if(tag == "link")){
                element.href = src;
                element.rel = "stylesheet";
            }else{
                element.src = src;
            }
            document.body.appendChild(element);
            loadeds.push(key);
            console.log("chargement du fichier " + key + ' : ' + scripts[key]);
            if(next <= (scripts.length -1)){
                element.onload = function(){
                    add(next);
                }
            }
        }
    };
    add();
}
<span class="redactor-invisible-space">if(window.addEventListener){
    window.addEventListener("load", deferLoadingFile, false);
}else if(window.attachEvent){
    window.attachEvent("onload", deferLoadingFile);
}else{window.onload = deferLoadingFile;}</span>
</script>

Dans l'exemple ci-dessus, j'appelle les librairies javascript jQuery et Bootstrap, puis en dernier le fichier init.min.js, qui contient des fonctions faisant appel aux deux librairies précédentes.

Des fichiers bien cachés

Pour éviter des appels incessants et surtout inutiles à certains fichiers, il est vital que ceux ci puissent être mis en cache pour une période minimale, ainsi que d'indiquer à votre serveur qu'il les compresse pour les rendre plus légers. C'est la partie la plus facile, il suffit d'ajouter quelques lignes dans votre fichier .htaccess, au pire de le créer si vous n'en avez pas.

En premier lieu, la gestion de délai d'expiration des différents types de fichiers. Le Expire header permet d’indiquer que certains types de fichiers peuvent rester en cache dans le navigateur du visiteur pendant une durée déterminée, sans que le navigateur n’ait besoin de faire des requêtes pour vérifier la validité du cache.

# Expires headers (contrôle du cache)
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault                          "access plus 1 month"
# cache.appcache (FF 3.6)
  ExpiresByType text/cache-manifest       "access plus 0 seconds"
# document html
  ExpiresByType text/html                 "access plus 1 month"
  ExpiresByType application/xhtml+xml       "access plus 1 month"
# Datas
  ExpiresByType text/xml                  "access plus 0 seconds"
  ExpiresByType application/xml           "access plus 0 seconds"
  ExpiresByType application/json          "access plus 0 seconds"
# RSS
  ExpiresByType application/rss+xml       "access plus 1 hour"
# Favicon
  ExpiresByType image/x-icon              "access plus 1 year"
# Medias: images, video, audio
  ExpiresByType image/gif                 "access plus 1 month"
  ExpiresByType image/png                 "access plus 1 month"
  ExpiresByType image/jpg                 "access plus 1 month"
  ExpiresByType image/jpeg                "access plus 1 month"
  ExpiresByType video/ogg                 "access plus 1 month"
  ExpiresByType audio/ogg                 "access plus 1 month"
  ExpiresByType video/mp4                 "access plus 1 month"
  ExpiresByType video/webm                "access plus 1 month"
# HTC (css3pie)
  ExpiresByType text/x-component          "access plus 1 month"
# Webfonts
  ExpiresByType font/truetype             "access plus 1 month"
  ExpiresByType font/opentype             "access plus 1 month"
  ExpiresByType application/font-woff     "access plus 1 month"
  ExpiresByType application/x-font-woff   "access plus 1 month"
  ExpiresByType application/font-woff2    "access plus 1 month"
  ExpiresByType image/svg+xml             "access plus 1 month"
  ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
# CSS & JavaScript
  ExpiresByType text/css                  "access plus 1 month"
  ExpiresByType application/javascript    "access plus 1 month"
  ExpiresByType text/javascript           "access plus 1 month"
  ExpiresByType text/x-javascript         "access 1 month"
  ExpiresByType application/x-javascript  "access plus 1 month"
  ExpiresByType application/x-shockwave-flash "access plus 1 month"
</IfModule>

Puis la gestion du type de cache selon le type de fichier. Le cache control est un complément de l’expire headers, en fonction du serveur que vous avez ou du navigateur utilisé par vos visiteurs. Ces paramètres vont déterminer une durée de cache par type de fichier.

<IfModule mod_headers.c>
    <filesMatch "\.(ico|jpe?g|png|gif|swf)$">
        Header set Cache-Control "public"
    </filesMatch>
    <filesMatch "\.(css)$">
        Header set Cache-Control "public"
    </filesMatch>
    <filesMatch "\.(js)$">
        Header set Cache-Control "private"
    </filesMatch>
    <filesMatch "\.(x?html?|php)$">
        Header set Cache-Control "private, must-revalidate"
    </filesMatch>
</IfModule>

Et enfin, activez la compression Gzip des fichiers en sortie de votre serveur. Cela va accélérer le temps de chargement, et réduire la bande passante utilisée. Attention cependant, car cette compression n’est pas supportée par tous les navigateurs et ne fonctionnera que sur des serveurs apaches 2.x. Testez donc bien votre site sur plusieurs navigateurs après la mise en place de ce code.

<IfModule mod_deflate.c>
  # Compression HTML, CSS, JavaScript, Texte, XML & typos
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
  AddOutputFilterByType DEFLATE application/x-font
  AddOutputFilterByType DEFLATE application/x-font-opentype
  AddOutputFilterByType DEFLATE application/x-font-otf
  AddOutputFilterByType DEFLATE application/x-font-truetype
  AddOutputFilterByType DEFLATE application/x-font-ttf
  AddOutputFilterByType DEFLATE application/x-font-woff
  AddOutputFilterByType DEFLATE application/font-woff
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE font/opentype
  AddOutputFilterByType DEFLATE font/otf
  AddOutputFilterByType DEFLATE font/ttf
  AddOutputFilterByType DEFLATE image/svg+xml
  AddOutputFilterByType DEFLATE image/x-icon
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/javascript
  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/xml
  # correction d'erreurs sur les anciens navigateurs
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
  Header append Vary User-Agent
</Ifmodule>

Si votre serveur a du mal avec certains types mime de fichiers, vous pouvez ajouter ces lignes...

<IfModule mod_mime.c>
    AddType application/javascript          js
    AddType application/vnd.ms-fontobject   eot
    AddType application/x-font-ttf          ttf ttc
    AddType font/opentype                   otf
    AddType application/x-font-woff         woff
    AddType image/svg+xml                   svg svgz 
    AddEncoding gzip                        svgz
</Ifmodule>

Et pour finir, désactiver les « Etags », ce qui va permettre de réduire encore le nombre de requêtes et la bande passante utilisée. Un etag permet de différencier deux versions d’un document ou d’un fichier. Cet Etag est transmis entre votre ordinateur et le serveur lors des requêtes HTTP. Son but est de vérifier si le document a été modifié. Si le fichier est identique, le navigateur utilisera son cache. Mais lors de chaque requête, les informations etags vont être transmises inutilement.

Header unset ETag
FileETag None

Réduire la taille des fichiers

Minifier est le terme le plus utilisé en ce domaine, et cela consiste à réduire la taille des fichiers à leur plus simple expression en compactant leur contenu en supprimant les espace vides, les retours chariot, et dans certains cas en remplaçant les noms de variables par des lettres pour le javascript. C'est la aussi assez facile, autant pour les utilisateurs de CMS, pour qui une pléthore de plugins existent pour gérer cela, que pour les autres qui pourront employer aussi bien des services en ligne (générators) que des logiciels spécialement dédiés, tel que scriptm qui permet de minifier les fichiers javascript et css, et qui est en libre téléchargement sur le site romeolight.com, site qui propose également HTMLminify dans le même esprit pour vos pages html et aspx (curieusement pas le php). Ces logiciels tournent sous Windows, mais il en existe aussi pour Mac. Les plus aguerris préfèreront utiliser Grunt.js pour automatiser les tâches de minification, compilation et concaténation de leurs fichiers. Pour ceux qui ne connaissent pas, voici un très bon tutoriel sur l'utilisation de Grunt qui tourne sous Node.js.

Des images bien compressées

Le poids et/ou les dimensions de vos images de votre site ne sont pas optimisées ? Dans ce cas Google vous le fait savoir en baissant votre note ! En effet, pourquoi charger l'image du header qui fait 1170 pixels de large, alors que votre visiteur ne possède qu'un écran 19 pouces ou encore une tablette, voire un smartphone ? A plus forte raison s'il s'agit d'un slider qui va charger nombre d'images au mêmes dimensions, faisant chacune plus de 300 Ko alors qu'elles pourraient peser beaucoup moins.

Certes, vous pouvez utiliser des outils tels que FastStone Photo Resizer pour traiter vos images en lots, et ainsi les décliner en plusieurs tailles rapidement, mais dans le cas d'un site dynamique, cela va rapidement s'avérer fastidieux. Pour ma part, j'ai opté pour la solution proposée par adaptive-images, très facile à mettre en place, et qui va faire le sale boulot à votre place.

Cette solution est principalement en langage .php, avec une petite ligne de code en javascript, et une autre à ajouter à votre fichier .htaccess. L'ensemble fonctionne de la manière suivante : La ligne de javascript va détecter la résolution de votre écran en incluant le pixel-ratio, et va créer un cookie en y stockant ces informations. La ligne du .htaccess va rediriger chaque requête image vers le fichier php, qui après avoir récupéré les valeurs du cookie généré précédemment, va comparer la taille de votre image à celle de votre écran. Si l'image est plus grande, le système va créer un nouveau répertoire correspondant à la résolution trouvée, et y copier une image redimensionnée avant de vous la servir, le tout à la volée.

A votre visite suivante, ou si votre site a déjà reçu la visite d'un périphérique ayant la même résolution que vous, le script va vérifier si l'image correspondant à votre taille d'écran existe, et le cas échéant, vous la renvoyer directement... le top L'ensemble est simple à mettre en place, il suffit pour cela une fois le script téléchargé et décompressé, de mette à la racine de votre site le fichier « adaptive-images.php » et d'y ajouter également le fichier « .htaccess ». Si vous avez suivi cet article, vous possédez déjà ce fichier, il vous suffit donc d'y ajouter ces lignes, ou les concaténer si vous avez déjà <IfModule mod_rewrite.c> en place:

<IfModule mod_rewrite.c>
  Options +FollowSymlinks
  RewriteEngine On
  # Adaptive-Images -----------------------------------------------------------------------------------
  # Add any directories you wish to omit from the Adaptive-Images process on a new line, as follows:
  # RewriteCond %{REQUEST_URI} !ignore-this-directory
  # RewriteCond %{REQUEST_URI} !and-ignore-this-directory-too
  RewriteCond %{REQUEST_URI} !assets
  # don't apply the AI behaviour to images inside AI's cache folder:
  RewriteCond %{REQUEST_URI} !ai-cache
  # Send any GIF, JPG, or PNG request that IS NOT stored inside one of the above directories
  # to adaptive-images.php so we can select appropriately sized versions
  RewriteRule \.(?:jpe?g|gif|png)$ adaptive-images.php
  # END Adaptive-Images -------------------------------------------------------------------------------
</IfModule>

Puis ensuite d'ajouter cette ligne javascript le plus haut possible entre les balises <head> et </head> (avant les autres appels css ou javascript) :

<script> document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/'; </script>

Reste ensuite à paramétrer quelques variables en tout début du fichier « adaptive-images.php » :

<?php 
/* CONFIG ----------------------------------------------------------------------------------------------- */
$resolutions   = array(1382, 992, 768, 480); // les resolutions d'écran à supporter en pixels (break-points)
$cache_path    = "ai-cache"; // le nom du répertoire ou stocker les images redimmensionnées
$jpg_quality   = 75; // la qualité des images générées (entre 0 et 100)
$sharpen       = TRUE; // Optimisation de la netteté des images
$watch_cache   = TRUE; // vérifier que l'image est adaptée et non périmée
$browser_cache = 60*60*24*7; // Durée de mise en cache (7 jours par défaut) 
?>

J'ai par contre légèrement modifié certaines parties pour y apporter quelques améliorations. En premier lieu, pourquoi appeler le cookie à chaque nouvelle page puisque les informations qui y sont contenues ne changeront pas (résolution d'écran) ? L'idéal est de stocker les valeurs du cookie dans une variable de session, mais si il est facile d'attribuer une valeur php à du javascript, l'inverse ne fonctionne pas. J'ai donc ajouté quelques lignes javascript qui, immédiatement après la création du cookie, ajoutent une iframe invisible ayant pour source un fichier php, et à qui les valeurs du cookie sont envoyées en GET.

Ce fichier php initialise une variable de session comportant les valeurs reçues, ce qui va permettre d'éviter le rechargement systématique du cookie au profit de la variable de session, plus rapide. Bien sûr, une fois la session créée, l'iframe est automatiquement détruite, ne laissant aucune trace.

Voici la fonction appelée entre les balises <head> et </head> en remplacement de la petite ligne javascript citée plus haut :

<?php 
// mémorisation des données de résolution
function storeResolution(){
    $resolution  = '<script id="scrres">'."\n";
    $resolution .= 'var screen_resolution = Math.max(screen.width,screen.height)+("devicePixelRatio" in window ? ","+devicePixelRatio : ",1");'."\n";
    $resolution .= 'document.cookie=\'resolution=\'+screen_resolution+\'; path=/\';'."\n";
    $resolution .= 'var scrres_tag = document.getElementById("scrres"), iframe = document.createElement("iframe");'."\n";
    $resolution .= 'iframe.scrolling   = "no";'."\n";
    $resolution .= 'iframe.frameborder = "0";'."\n";
    $resolution .= 'iframe.width       = "0";'."\n";
    $resolution .= 'iframe.id          = "scr_frm";'."\n";
    $resolution .= 'iframe.height      = "0";'."\n";
    $resolution .= 'iframe.src         = "stock_resolution.php?resolution=\'"+screen_resolution+"\'";'."\n";
    $resolution .= 'iframe.onload      = function(){setTimeout(function(){var scr_frm = window.parent.document.getElementById("scr_frm");scr_frm.parentNode.removeChild(scr_frm);}, 50);}'."\n";
    $resolution .= 'scrres_tag.parentNode.insertBefore(iframe, scrres_tag.nextSibling);'."\n";
    $resolution .= ''."\n";
    $resolution .= '</script>'."\n";
    return $resolution;
}
?>

Pour appeler cette fonction :

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Votre titre</title>
    <?php echo storeResolution(); ?>
  </head>
  <body>...</body>
</html>

Le contenu du fichier stock_resolution.php :

<?php 
session_start();
header('Content-Type: text/html; charset=utf-8');
if(isset($_GET['resolution']) && !empty($_GET['resolution'])){
    $resolution = trim($_GET['resolution']);
    $resolution = strip_tags($resolution);
    list($res, $pr) = explode(',', $resolution);
    $res                    = preg_replace("/[^0-9]/", "", $res);
    $pr                     = preg_replace("/[^0-9]/", "", $pr);
    $resolution             = "$res,$pr";
    $_SESSION['resolution'] = $resolution;
} 
?>

Il va falloir maintenant modifier le fichier « adaptive-images.php » pour lui indiquer qu'il faut vérifier si la variable de session existe avant de charger le cookie (ligne 243), remplacer :

<?php 
/* Check to see if a valid cookie exists */
if (isset($_COOKIE['resolution'])) {
    $cookie_value = $_COOKIE['resolution'];
    // does the cookie look valid? [whole number, comma, potential floating number]
    if (! preg_match("/^[0-9]+[,]*[0-9\.]+$/", "$cookie_value")) { // no it doesn't look valid
        setcookie("resolution", "$cookie_value", time()-100); // delete the mangled cookie
    }else { // the cookie is valid, do stuff with it
        $cookie_data   = explode(",", $_COOKIE['resolution']);
        $client_width  = (int) $cookie_data[0]; // the base resolution (CSS pixels)
        $total_width   = $client_width;
        $pixel_density = 1; // set a default, used for non-retina style JS snippet
        if (@$cookie_data[1]) { // the device's pixel density factor (physical pixels per CSS pixel)
            $pixel_density = $cookie_data[1];
        } 
    ...
}
?>

par

<?php 
/* Check to see if a valid cookie exists */
if(isset($_SESSION['resolution']) || isset($_COOKIE['resolution'])) {
    $cookie_value = (isset($_SESSION['resolution']))? $_SESSION['resolution'] : $_COOKIE['resolution'];
    // does the cookie look valid? [whole number, comma, potential floating number]
    if (! preg_match("/^[0-9]+[,]*[0-9\.]+$/", "$cookie_value")) { // no it doesn't look valid
      setcookie("resolution", "$cookie_value", time()-100); // delete the mangled cookie
      $_SESSION['resolution'] = $cookie_value;
    }else { // the cookie is valid, do stuff with it
      if(!isset($_SESSION['resolution'])){ // if no session detected
          $_SESSION['resolution'] = $cookie_value;
      }
      $cookie_data   = explode(",", $_COOKIE['resolution']);
      $client_width  = (int) $cookie_data[0]; // the base resolution (CSS pixels)
      $total_width   = $client_width;
      $pixel_density = 1; // set a default, used for non-retina style JS snippet
      if (@$cookie_data[1]) { // the device's pixel density factor (physical pixels per CSS pixel)
          $pixel_density = $cookie_data[1];
      } 
    ...
}
?>

Puis au passage, on va optimiser deux autres petits points, toujours dans le fichier « adaptive-images.php ». Nous allons modifier la fonction sendImage() à la ligne 58 en lui ajoutant un header('last-modified'), ce qui va permettre d'améliorer la mise en cache :

<?php 
/* helper function: Send headers and returns an image. */
function sendImage($filename, $browser_cache) {
    $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
    if (in_array($extension, array('png', 'gif', 'jpeg'))) {
        header("Content-Type: image/".$extension);
    } else {
        header("Content-Type: image/jpeg");
    }
    header("Cache-Control: private, max-age=".$browser_cache);
    header('Expires: '.gmdate('D, d M Y H:i:s', time()+$browser_cache).' GMT');
    header('Content-Length: '.filesize($filename));
    header('Last-Modified: '.gmdate( 'D, d M Y H:i:s', filemtime($filename)).' GMT'); /* Ajouté : amélioration de la mise en cache */
    readfile($filename);
    exit();
} 
?>

Puis nous allons améliorer sensiblement la fonction de détection de mobile intégrée, en remplacant la fonction is_mobile() à la ligne 35 :

<?php 
/* Mobile detection NOTE: only used in the event a cookie isn't available. */
function is_mobile() {
    $userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
    return strpos($userAgent, 'mobile');
} 
?>

Par celle ci qui ratisse nettement plus large (merci à detectmobilebrowsers.com) :

<?php 
/* Mobile detection NOTE: only used in the event a cookie isn't available. (modifié pour une plus large détection de mobiles) */
function is_mobile() {
    $userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
    if(preg_match('/(android|bb\d+|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',$useragent)||preg_match('/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',substr($useragent,0,4)) || strpos($userAgent, 'mobile')){
        return true;
    }
    return false;
} 
?>

Conclusion...

Voilà, c'est tout pour aujourd'hui, Tous les aspects n'ont pas été traités ici, mais une partie importante. j'espère que cela a pu aider certains d'entre vous qui rament un peu à obtenir des points supplémentaires sur Google pagespeed, et ainsi améliorer un peu votre référencement, ou tout du moins, ne pas être pénalisé par ce géant du web. Pour ma part, j'ai pu en partie grâce à cela obtenir un joli double A sur GTmetrix comme vous pouvez le constater sur l'image ci-dessus, la partie optimisation a donc bien été payante.

Les suggestions sont bien entendu les bienvenues, et n'hésitez pas à partager


Par vision-design.fr - Reproduction non commerciale libre sous réserve de mention du lien source.