Suite au partage de Single Point of Failure : votre site web indisponible à cause des scripts externes ? par un collègue @iAdvize, je souhaitais partager ici mon retour d'expérience sur cette problématique.
L'article soulève effectivement les différents problèmes posés par la dépendance sur des services tiers — que cela soit des indisponibilités ou la conséquence des blocages de scripts via ad-blockers — mais ne donne pas réellement de solutions pratiques.
Voici donc les solutions que j'ai pu mettre en place en production sur Redsmin et feu Bringr pour gérer le cas où une librairie tierce (par exemple Mixpanel ou Google Analytics) est indisponible ou bloquée. La solution se résume en deux mots: découplage et isolation.
Découplage: il est vital pour la disponibilité de l'application de communiquer avec les composants externes de manière découplée. L'application elle-même ne doit pas avoir une connaissance forte des composants externes et de ce qu'ils offrent car ils peuvent ne pas exister. Par exemple, l'objet global Mixpanel offre une méthode track pouvant être bloquée. De même, Google Analytics expose une fonction globale "ga" qui peut être indéfinie à cause d'un ad-blocker.
La solution pour assurer un découplage fort consiste par exemple à utiliser un message ou event-bus (e.g. un dispatcher ou event emitter) pour notifier depuis l'application les évènements intéressants à suivre. Pour rappel, l'intérêt de passer par un event-bus est que l'émetteur n'a aucune connaissance du ou des destinataires. Ainsi si le chargement de Mixpanel ou de Google Analytics n'a pu être effectué (à cause d'une indisponibilité ou d'un blocage d'un adblock-like) l'application émettra toujours ses évènements, il n'y aura aucun listener, l'indisponibilité des composants externes sera donc transparente pour l'application.
Isolation: nous encapsulons chaque composant externe dans un module indépendant qui est connecté avec le reste de l'application par le message ou event-bus (e.g. un event emitter). Certains ad-block peuvent laisser exister l'objet global (e.g. Mixpanel) mais supprime toutes ses méthodes (e.g. track), il est donc important d'encapsuler l'appel au composant tier (e.g. Mixpanel.track) dans un try/catch ce qui permet de ne pas bloquer l'exécution des listeners suivants à cause d'une exception.
Cette approche nous permet d'avoir Google Analytics, Mixpanel, UserVoice etc... en production sans nous soucier de la configuration du navigateur, des extensions de blocage ou des indisponibilités des composants externes.