Histoires de performances

A l’origine, SimpleManager est un projet de veille technologique destiné à éprouver les outils et pratiques du moment. Petite présentation de la stratégie liée aux performances. 

Choix techniques

Les performances applicatives dépendent d’une chaîne dont il faut optimiser les maillons. Les implémentations du back-end et du front-end, les flux échangés, la base de données, le hardware, la résistance à la charge, tout doit être étudié pour éviter le moindre ralentissement.

Le front-end

Pour SimpleManager, j’ai choisi de développer un front-end dynamique et fluide basé sur VueJS2 + Vuex, un framework javascript réputé pour ses performances et sa légèreté. Je l’ai couplé à un bootstrap via un Admin LTE élagué, son JQuery et quelques librairies légères et nécessaires. Bien que largement répandu, il ne s’agit pas du framework CSS le plus « lite » du marché, d’où l’importance de ne pas l’encombrer de dizaines d’autres plugins.

L’interface de SimpleManager

Je voulais un front-end qui se charge très rapidement, même avec une connexion lente. Y intégrer la partie dynamique de l’ensemble des fonctionnalités de SimpleManager n’était donc pas possible, car cela aurait augmenté la densité du code. Je me suis donc borné à implémenter ce qui est nécessaire pour le layout et les fonctionnalités communes à chaque page : menu, notifications, gestion de la navigation, moteur de recherche, etc.

Chargement de la page « Mes produits » ci-dessus

Du coup, le code spécifique à certaines fonctionnalités doit être délivré par le serveur au fur et à mesure. Cela peut se faire sous la forme de chargements dynamiques ou via une intégration au flux Json. Mon serveur « REST » lié au front-end est donc hybride, car outre les données utiles, il embarque du code  spécifique aux fonctionnalités non-redondantes de l’interface. Un choix que l’on peut contester, mais que j’ai pris le risque d’assumer dans un premier temps.

Le back-end

Les choix liés au back-end sont parfois difficiles, car de nombreux paramètres sont à prendre en compte. En particulier la pérennité de la solution, la cohérence et la clarté de son implémentation, son évolutivité, sa scalabilité et ses performances globales. Ce dernier point étant la priorité absolue. Difficile d’être concis.

Couches de bibliothèques du générique au spécifique

Côté framework, PHP7 offre un large choix. Il est cependant risqué pour la pérennité de tabler sur un projet qui impose des versions majeures tous les 5 ans, nécessitant une refonte importante du code. D’autre part, l’organisation des sources doit être adaptée aux méthodes de travail, et pour assurer de bonnes performances il est important d’éviter les chargements inutiles (bootstrap, système de plugin lourd, configuration complexe, etc.). Après avoir étudié et utilisé Symphony, Laravel, ZF et leurs concurrents des années durant, j’en ai conclu que les implémentations et architectures proposées par ces merveilleuses solutions s’avèrent perfectibles compte tenu de mes besoins. Cependant, choisir le meilleur de ces technologies est aujourd’hui facilité par l’excellent « composer » dont les ressources sont de plus en plus compatibles grâce au respect croissant des PSR, que tout projet sérieux se doit d’intégrer.

Organisation du code SimpleManager

Mon choix s’est donc porté sur une implémentation minimale de l’architecture applicative, optimisée pour mes besoins. Un gestionnaire d’objets limite au maximum les instanciations, les appels dynamiques et l’utilisation de la mémoire. Les librairies externes sont liées au framework métier au moyen de proxies de manière à ce qu’elles soient toutes remplaçables et maintenables.

Enfin, j’ai mis en place deux solutions délicates mais que je ne regrette pas aujourd’hui : d’une part un système de « pré-compilation » par génération de code destiné à limiter les exécutions redondantes et les appels dynamiques, d’autre part un mécanisme d’exécution de code en différé pour tout ce qui n’est pas nécessaire au calcul de la réponse. PHP7 est un langage interprété fantastique et performant, mais il lui manque encore cruellement la possibilité d’avoir des objets « statefull » et des exécution concurrentes.

Administration de SimpleManager : générateurs et nettoyages

Côté SGBD, après avoir essayé de nombreuses alternatives NoSQL, j’en ai conclu que pour les besoins spécifiques à mon métier, MySQL restait une très bonne solution. En apportant un soin particulier à la mise en place de l’architecture, des liens, des indexes, des déclencheurs et des vues. MySQL apporte de la performance par sa maîtrise native des jeux de caractères, l’utilisation de types de données spécifiques accompagnés de leurs procédures, utiles en particulier pour les performances en lecture. Pour les besoins en scalabilité, SimpleManager est doté de deux bases, la première pour l’administration générale des client et la deuxième, destinée à être dupliquée sur plusieurs serveurs, pour les fonctionnalités métier.

En complément, j’utilise massivement l’excellent Redis pour les manipulations d’information, les exécutions différées et le cache à tous les niveaux. Je m’oblige toujours à ce que les réponses soient instantanées, en l’occurrence inférieures à 200ms quand mon cache est désactivé.

Dernier point difficile à gérer pour le backend : l’augmentation de la densité de code. L’architecture doit être pensée pour que la multiplication des modules et des plugins ne ralentisse pas les performances. Le lazy loading, la pré-compilation et pas mal de rigueur sont nécessaires. Seuls quelques choix technologiques s’avèrent durs quand l’existant ne permet pas les performances voulues. C’est le cas de la génération PDF. J’ai opté au début pour la LibHaru, dont les performances sont absolument fantastiques, avant de devoir me rabattre sur FPDF faute de compatibilité avec les nouvelles versions de PHP.

Les résultats

Outre la scalabilité qui n’a pas encore été testée en production, je suis vraiment satisfait des performances globales de la solution, ainsi que de sa stabilité. Si vous testez des applications PHP sur Raspberry Pi, vous vous rendrez compte qu’elle « rament » presque toutes. Les réponses de SimpleManager sont quasi-instantanées, sauf pour des tâches spécifiques comme les calculs PDF pour lesquels il faut attendre 300 à 500ms.

Mini-serveur Raspberry Pi

Si c’était à refaire

Ces choix me conviendraient encore parfaitement. Cependant les technologies évoluent. Pour optimiser davantage, j’opterais certainement pour les alternatives suivantes après m’être assuré qu’elles soient pérennes et intégrables en continu :

  • Un framework-extension, tel que Yaf ou Phalcon, ce dernier étant certainement le plus prometteur à ce jour. Quand j’ai commencé à utiliser ZF 1, je me suis tout de suite dit que ce genre d’implémentation serait parfaitement possible (et pertinente) en C, sous forme d’extension.
  • Côté front-end, je garde VueJS ou le remplace par un équivalent pérenne à coupler avec un Semantic UI ou tout autre framework CSS simple, performant et doté d’une communauté assez solide. Et je choisirais finalement :
    • D’une part de déporter toute l’implémentation javascript sur le front-end dans la mesure où le code non nécessaire est chargé en différé (ce que webpack gère plutôt bien).
    • D’autre part d’implémenter ce front-end en application 100% progressive, communiquant (ou pas) avec un back-end full-REST.
  • Côté back-end, si je devais faire des choix vraiment radicaux… je remplacerais PHP par Javascript/Node.js (performance et pérennité) ou Go (super-performances). Il faut avouer que si PHP est irremplaçable en terme de souplesse et d’adaptation, Javascript est aujourd’hui la technologie d’avenir que tout développeur se doit de maîtriser, à l’instar de l’anglais pour nos communications verbales.
  • Côté SGBD, la solution dépend fortement du métier. Dans le cas de SimpleManager, qui manipule de l’information critique très structurée dont l’intégrité est essentielle, le choix d’une base relationnelle éprouvée est à mon avis, encore aujourd’hui, pertinent. Les données moins structurées mais massives, soumises à des traitements « big-data », disposent de solutions NoSQL fiables voir des services payants de manipulation de données fournis par les GAFAM, acteurs technologiquement à la pointe.
  • Enfin, je n’ai pas encore parlé du moteur de recherche dont l’optimisation a pris un certain temps. Basé sur MySQL, Redis et des mécanismes de translittération, il est possible de le faire évoluer vers une solution plus élaborée telle qu’ElasticSearch.

Toutes ces informations sont sujettes à évolution dans la mesure où l’écosystème web et mes connaissances évoluent tous les jours.

Laisser un commentaire