Voilà un sujet qui est souvent revenu autour de la toile ces derniers temps : la compression gzip avec Domino. Et avec la multiplication des frameworks javascript plus puissants mais aussi plus lourds les uns que les autres (Ext, YUI, Dojo, etc), on comprend aisément pourquoi ce sujet est devenu critique. Initialement prévue pour la R7, puis finalement non (et voici peut-être pourquoi), plusieurs solutions personnalisées de compression gzip ont vu le jour ; en substance :
- Tout d'abord la compression native mais cachée et non supportée officiellement, qui n'a donné que des résultats désastreux de mon coté (bases extrêmement lentes sinon inutilisables).
- Ensuite, l'ajout de fichiers compressés dans les ressources partagées, qui nécessite, comme l'intitulé l'indique, de réaliser préalablement la compression manuellement, ce qui semble difficilement envisageable quand on souhaite appliquer la compression gzip à l'ensemble de ses bases existantes.
- Enfin, l'utilisation d'une servlet qui compresse à la volée, mais qui, tel que proposé, implique la modification de tous les liens existant, ce qui présente autant d'inconvénients que la solution précédente.
La solution que je vais vous décrire est un peu un amalgame des deux dernières ; une servlet pour compresser à la volée les fichiers, mais (et c'est là toute la magie) avec des règles de sites web spécifiques pour réécrire les URL et compresser de manière transparente, sans toucher aux liens existants.
J'attire votre attention sur le fait que le peu de tests réalisés dans des environnements de production ne se sont pas révélés à la hauteur des attentes, et en outre, après quelques jours d'activité, la tâche HTTP a commencé à montrer des signes de faiblesses et une consommation mémoire anormalement élevée. C'est peut-être dû à l'utilisation intensive de la servlet, c'est peut-être dû à autre chose (mauvais paramétrage ?). Cette première expérience me laisse perplexe car j'utilise des servlets pour d'autres applis à fort taux de visite sans le moindre problème. Néanmoins, je reste convaincu que le concept est bon et c'est pourquoi je vous le présente, en attendant de trouver le fin mot de l'histoire. Gardez tout de même ceci en tête avant de le déployer sur vos serveurs !
La servlet de proxy
Vous vous souvenez de l'agent de proxy Domino ? Vous ne l'avez certainement pas vu puisque cela n'apparaissait que dans les commentaires, mais à l'époque je l'avais également codé sous forme de servlet. Et bien j'ai ajouté quelques fonctionnalités à cette dernière, et notamment celle de gzipper le contenu avant de le renvoyer vers le client (paramètre &gzip=1).
Vous pouvez la chopper ici :
Pour ce qui est de l'installation de la servlet, je vous renvoie à cet article un peu vieux mais plus ou moins toujours d'actualité : Domino development with servlets, ou sinon, en quelques mots, vous déposez le fichier ProxyServlet.class dans votre répertoire data\domino\servlets, et vous vous assurez que le gestionnaire de servlets de Domino est activé (document serveur > Internet protocols > Domino web engine).
Les règles de sites web
Vient ensuite la partie plus amusante : les règles de sites web1. Les règles de substitutions et de redirections font un peu penser à une sorte de mod_rewrite du pauvre, mais avec un peu d'astuce on peut arriver malgré tout à faire des choses sympathiques.
L'idée va être la suivante : pour tous les fichiers ayant l'extension .js ou .css, on redirige (en interne) vers la servlet de proxy avec en paramètre l'URL du fichier susnommé. Le tout est alors totalement transparent pour l'utilisateur. Simple, non ? En réalité, un peu moins que ça, car les possibilités de réécriture des règles de sites web sont limitées et il va falloir mettre en place 2 règles de substitution par extension pour arriver proprement à nos fins.
La première règle va transformer les appels vers les fichiers *.js vers la servlet de proxy avec pour extension de fichier *.js2gzip, tandis que la seconde va intercepter les appels aux fichiers *.js2gzip pour les retransformer en *.js, ce afin de conserver le bon type MIME. Et de même pour les fichiers *.css. Sans cela, la tâche HTTP chercherait à invoquer la servlet indéfiniment (boucle infinie), jusqu'au plantage de la tâche.
*.js -> /servlet/ProxyServlet?url=*.js2gzip&gzip=1&expires=0
*.js2gzip -> *.js
Extrait de ma config :

Attention, notez bien que les règles définies dans la partie Global web settings ne s'appliquent pas pour le site par défaut, avec Domino 7.0.2 FP2 du moins. Cela relève probablement du bug.
Conclusion
A l'heure où j'écris ceci, je ne ne peux vous fournir de chiffre, mais les résultats lors de mes tests se sont montrés sans appels, et les temps d'affichage des applications massives (remplies de fichiers js et de css) nettement réduits au premier chargement. Et ce - c'est là l'intérêt - sans changer la moindre ligne de code des applis. Un simple test avec Firebug et YSlow le prouve.
Je n'explique cependant toujours pas pourquoi les performances de la tâche HTTP se sont dégradées avec le temps, mais je vais continuer à chercher. La solution est peut-être un tuning plus fin du côté des entêtes HTTP d'expiration (voir le premier point de ce billet de Julian Robichaux) afin de soulager un peu la tâche HTTP. Quoi qu'il en soit, si jamais vous essayez de votre côté, n'hésitez pas à me dire ce que cela donne.
Edit : Voilà quelques stats pour illustrer ces propos :

Edit #2 : La solution été a priori trouvée (merci Smicky) ; utiliser d'un côté des connexions "fermées" entre le proxy et le serveur Domino, et conserver des connexions persistantes entre le proxy et le navigateur (ce qui implique de retourner la taille du contenu gzippé via l'entête Content-Length). Le hic, c'est que ça pose des tas de problèmes dans IE ; les CSS ou les JS se perdent très souvent dans la nature. C'est un problème connu, il y a des tas de références là dessus sur Google, et presque autant de patchs chez Microsoft selon les versions de Windows et/ou d'IE. La solution globalement préconisée : ne pas utiliser la compression gzip avec IE. Super. N'ayant pas trouvé de workaround malgré un bon paquet d'heures perdues passées sur le sujet, j'abandonne. C'était pourtant une belle idée.
1 : Pour cela, vous devez nécessairement utiliser les documents de sites internet (document serveur > onglet Basics > Load Internet configurations from Server\Internet Sites documents).