English version will be available soon.
Dans l'épisode précédent
Cette publication constitue le troisième épisode de mon "feuilleton de l'été" consacré à StatusNet. Vous pouvez consulter les précédents là:
- Part 1: Installer sa propre instance StatusNet avec PHP-FPM et Nginx
- Part 2: Optimiser les performances et les fonctionnalités de son instance StatusNet
- Part 3: Une extension pour optimiser les performances de son instance StatusNet
Aujourd'hui, nous allons nous concentrer sur les optimisations côté client. Pour cela, nous utiliserons les outils PageSpeed et YSlow. Ce sera également l'occasion de découvrir le système de plugins intégré à StatusNet.
Introduction
De plus en plus, les mesures de performances web prennent de l'importance. Nous avons vu comment optimiser le backend (StatusNet lui-même), mais le frontend (votre navigateur) a également son importance.
Les optimisations côté client ont pour but d'accélérer et fluidifier le chargement des pages. 2 outils permettent de guider le développeur: Yslow et PageSpeed.
Les outils
À tout seigneur tout honneur, nous commencerons par le plus ancien: YSlow, développé par les équipes de Yahoo. Actuellement en version 3.0.3, il est disponible sous forme d'extension Firefox. Il mesure l'application de recommandations que vous pourrez trouver ici: Recommandations Yahoo.
Le second a, quant à lui, été développé par Google: il s'agit de PageSpeed. Il est disponible en version 1.11, lui aussi sous forme d'extension Firefox. Il mesure l'application des recommandations suivantes: Web Performance Best Practices.
L'intérêt de ces outils, outre le fait qu'ils sont disponibles sous forme d'extensions Firefox, est qu'ils ne s'appuient pas sur les même recommandations. Il est donc possible, et conseillé, de jouer sur les 2 tableaux. C'est bien entendu ce que nous allons faire.
Si ce n'est déjà fait, je vous conseille donc d'installer ces outils.
Vous pouvez également utiliser des services en ligne. Personnellement, j'utilise GTmetrix qui me permet de surveiller régulièrement mes sites web et, surtout, de conserver un historique des mesures réalisées. Ce point est particulièrement intéressant pour pouvoir mesurer l'impact de telle ou telle optimisation.
Le cahier des charges
Si vous avez déjà lancé une analyse de votre instance StatusNet, vous avez déjà une petite idée des soucis que nous allons essayer de corriger. En vrac:
- Optimiser et fusionner les CSS
- Optimiser et fusionner les JS
- Optimisation des images
J'ajouterai à ces recommandations ma touche personnelle: lorsque vous vous rendez sur une page de profil d'un utilisateur StatusNet, par exemple le mien, vous pouvez voir la liste des abonnés et des abonnements de l'utilisateur, même si vous n'êtes pas vous même authentifié.
C'est sympa, mais dans mon cas, pas très cool: mon instance est hébergée sur un petit serveur. À petit serveur, "petites" ressources. Si je peux éviter de charger les avatars de chacun de mes abonnés/abonnements, mon serveur HTTP sera content. Accessoirement, cela permettra d'appliquer une recommandation supplémentaire: limiter le nombre de requêtes HTTP :)
Le cahier des charges que nous devrons respecter est donc:
- Cacher certains éléments des pages lorsque le visiteur n'est pas authentifié
- Modifier l'inclusion des feuilles de style CSS pour en limiter le nombre
- Modifier l'inclusion des scripts Javascript pour en limiter le nombre
Les extensions StatusNet
StatusNet dispose d'un système d'extensions (plugins). Ceci permet d'étendre les fonctionnalités de StatusNet sans pour autant avoir à modifier le code source. Il est même possible de modifier le comportement par défaut de StatusNet, toujours grâce aux extensions.
Nous allons donc naturellement utiliser ces possibilités pour arriver à nos fins.
Une extension déjà intégrée propose une partie de ce que l'on veut faire. Il s'agit de MobileProfile.
Cette extension désactive l'affichage d'une partie de la page, la colonne de droite, lorsque l'on y accède à partir d'un équipement mobile. C'est très exactement ce que nous voulons faire, à un détail près: dans notre cas, le critère sera le status authentifié ou non du visiteur.
En ce qui concerne l'optimisation de l'inclusion des CSS et autres Javascript en revanche, nous n'aurons pas d'autre choix que de modifier le comportement par défaut de l'application: en effet, ces actions sont réalisées au sein de la classe action et, pour autant que j'ai pu voir, aucun plugin ne modifie le comportement par défaut.
Nous allons donc nous en charger.
Les évènements dans StatusNet
Au cœur de StatusNet, tout ou presque est "évènements". L'arrivée d'un message, l'envoi d'un message, tout ceci est géré de manière évènementielle. Bien entendu, il en est de même de la construction et de l'affichage des pages HTML.
Les différents évènements disponibles sont décrits dans le fichier EVENTS à la racine de l'installation StatusNet.
Il est extrêment simple de s'inscrire pour pouvoir gérer un évènement. Par exemple:
- StartShowScripts
- Cet évènement déclenche l'inclusion du code HTML de chargement des scripts Javascript.
Un plugin peut donc s'inscrire à cet évènement, simplement en définissant une fonction onStartShowScripts. Simple, non ?
L'autre point important à connaitre pour développer un plugin concerne le code retour des gestionnaires d'évènement. La solution retenue par StatusNet est la suivante:
- Tout gestionnaire d'évènement doit retourner une valeur booléenne
- Si la valeur est
false, le traitement de l'évènement est interrompu. C'est notamment utilisé pour remplacer le comportement par défaut deStatusNet - Si la valeur est
true, le traitement de l'évènement continue. Pratique pour enrichir un évènement.
Les actions par défaut, pour autant que j'ai pu m'en apercevoir, sont définies dans la classe lib/action.php.
Nous savons donc maintenant, dans le principe tout au moins, comment "détourner" le flux d'exécution de StatusNet. Nous pouvons donc passer à l'étape suivante.
L'extension WebPerformances
(Vous aurez noté l'originalité du nom de l'extension)
L'idée est donc d'utiliser l'extension WebPerformances pour étendre les fonctionnalités de MobileProfile tout en remplaçant un certain nombre d'actions par défaut de StatusNet.
Commençons par créer le squelette de l'extension. À la racine de l'installation de StatusNet, il faut créer le répertoire de l'extension:
Le contenu de WebPerformancesPlugin.php est, pour l'instant:
Rien de notable pour le moment. La classe WebPerformancesPlugin étend la classe MobileProfilePlugin. C'est pour cette raison que j'ai ajouté un require PHP juste avant la définition de la classe: il permet de s'assurer que l'extension MobileProfile sera disponible lors de l'initialisation de notre extension WebPerformances.
Puisque notre extension étend l'extension MobileProfile, il est nécessaire que notre classe instancie sa classe parente:
À partir de maintenant, nous disposons d'ors et déjà de toutes les fonctions de la classe MobileProfilePlugin dans notre classe WebPerformancesPlugin.
L'extension MobileProfile
L'extension MobileProfile va définir une variable serveMobile en fonction du user-agent. À partir de la valeur de cette variable, l'extension va décider d'afficher, ou pas, telle ou telle partie de la page. Les évènements, qui nous intéressent, gérés par MobileProfile sont:
- StartShowStatusNetStyles
Showing StatusNet Style links
Dans cette fonction, l'évènement ne sera traité par l'extension que si on est en présence d'un équipement mobile. Dans le cas contraire, le traitement au sein de l'extension est stoppé. Mais le
return truelaisse la possibilité à une autre extension, ou àStatusNetd'appliquer une action par défaut.- StartShowHeader
Showing before the header container
Même topo ici, l'évènement ne sera traité que si un équipement mobile a été détecté. Dans le cas contraire, l'extension passe la main à l'action par défaut.
- StartShowAside
Showing before the Aside container
Dans le cas où un équipement mobile est détecté, la barre latérale droite est masquée. L'effet est obtenu grâce au
return falsequi interrompt tout traitement de cet évènement.
Améliorer l'extension MobileProfile
Maintenant que nous avons ciblé les fonctions à surcharger, il est temps de mettre les doigts dans le code. Je ne mettrai pas le code ici pour éviter d'avoir à mettre à jour le document à chaque nouvelle version. Vous pouvez télécharger l'extension WebPerformances et examiner le code à votre aise.
- StartShowHeader
Dans notre cas de figure, nous allons surcharger cette fonction pour simplifier l'affichage si l'utilisateur n'est pas authentifié.
Notez encore une fois le
return false. Cela signifie que le traitement de l'évènementStartShowHeadersera stoppé après cette extension. Notez également que, dans le cas d'un utilisateur authentifié, l'extensionWebPerformancespasse la main àMobileProfilesans faire quoique ce soit.Vous remarquerez au passage que l'appel à la fonction _showLogo a été supprimé. En effet, j'ai décidé de ne pas afficher de logo aux utilisateurs non authentifié (et oui, je fais ce que je veux avec mon code :p ).
- StartShowAside
Là encore, si l'utilisateur est authentifié, nous passons la main à l'extension
MobileProfiledont le comportement par défaut nous convient parfaitement.
Et c'est tout pour l'amélioration de l'extension MobileProfile. Passons à la suite, la modification du comportement par défaut de l'application.
Remplacer certaines actions par défaut
Nous cherchons ici à regrouper les feuilles de style et les scripts Javascript, pour limiter les requêtes HTTP nécessaires à leur chargement.
En ce qui concerne les feuilles de style, tout se passe dans la fonction onStartShowStatusNetStyles. Mais cette fonction est déjà surchargée par l'extension MobileProfile. Qu'à cela ne tienne, nous allons la détourner nous aussi.
- StartShowStatusNetStyles
Dans notre cas, nous voudrons bien entendu conserver le comportement de l'extension
MobileProfilequi affiche les feuilles de style adaptées au équipements mobiles, tout en remplaçant l'appel à$action->primaryCSSLink(). Cette fonction, définie dans le fichierlib/action.phpva insérer les feuilles de styles par défaut. Problème, il y en a 2 et nous n'en voulons qu'une.De plus, dans le cas où nous sommes en présence d'un utilisateur non authentifié et n'utilisant pas un équipement mobile, nous cacherons malgré tout la barre latérale. Dans ce cas, il faut aussi surcharger la feuille de style de manière à ce que la colonne de gauche occupe alors tout l'espace disponible. Compte tenu de la taille du style en question, il sera inséré directement dans la page. La fonction devient alors:
Ici, je n'ai pas voulu intégrer les feuilles de style des plugins. Il faut en effet fusionner les feuilles de styles entre elles et le nombre de combinaisons possibles en fonction des plugins utilisés est juste rédhibitoire.
Veuillez vous référer au fichier README fourni avec le plugin pour savoir comment mettre en place le système.
- StartShowJQueryScripts
Comme son nom l'indique, cette fonction est chargée d'insérer le code HTML pour charger les scripts JQuery. Par défaut, il y en a 4, plus un cinquième qui, sans être un script JQuery, peut toutefois être intégré avec les autres. La fonction devient:
Bien entendu, comme pour les feuilles de styles, il faut rassembler tous ces fichiers en 1 seul
- StartShowStatusNetScripts
Cet évènement n'est pas géré par le plugin
MobileProfile. Dans ce cas-ci, nous allons remplacer le comportement par défaut deStatusNet, défini dans le fichierlib/action.php.Plus précisément, l'affichage du code HTML de chargement du script
js/util.min.jsest géré dans la fonctionshowScriptsCe que nous voulons obtenir est simple: ne plus afficher le code HTML de chargement du script
js/util.min.jsdans la mesure où nous venons de l'intégrer àjs/wp-jquery_util.min.js. Il nous faut donc surcharger l'évènementStartShowStatusNetScriptsdans notre extension. Bien entendu, la fonction retournera lavaleurfalsede manière à stopper le traitement de l'évènement.
Conclusion
Voilà, nous avons vu comment étendre et modifier le comportement de StatusNet à partir d'un exemple, certes simple, mais représentatif de ce que l'on peut faire.
Sources et références
StatusNet
- StatusNet
- http://status.net/open-source/
- http://status.net/wiki/
- Plugins
- http://status.net/wiki/Plugins
- http://status.net/wiki/HOWTO_Make_a_Plugin
