¿Cómo evitar el Flickering en las herramientas de testing y personalización?
Es frecuente ver seriamente mermada, sino arruinada completamente, la experiencia de usuario en la ejecución de un test A/B o personalización al sufrir del temido efecto parpadeo (aka flickering en inglés). Pero, ¿qué es el flickering?
El efecto parpadeo o flickering se produce cuando al ejecutar una versión de un test, la versión por defecto o de control se visualiza unos segundos antes de ser sustituida por la variación. Los cambios realizados por la herramienta de testing se desencadenan con la interfaz ya renderizada y el cambio es visualizado en pantalla, lo que se traduce en una mala experiencia de usuario.
Seguro que, si llevas algún tiempo trabajando en optimización en cualquiera de sus vertientes y acrónimos (CRO, CXO, BXO, etc…) te ha pasado alguna vez. A mí al menos me ha pasado en distintas ocasiones e incluso recuerdo el primer test de redirección en el que participé, donde se cargaba la versión de control enviando el pixel de analítica antes de redireccionar a la alternativa. Es importante señalar en este punto la gran evolución que han experimentado este tipo de herramientas en los últimos años, aunque todavía hoy sigue siendo un asunto especialmente delicado de tratar a la hora de implementarlas.
¿Por qué se produce el flickering?
Cualquier herramienta actual de testing y personalización (Adobe Target, Optimize, Maxymiser, Dynamic Yield…) utilizan, en sus implementaciones estándar del lado de cliente, JavaScript para inyectar los cambios en el código HTML de las páginas.
El orden de ejecución de estos scripts es importante y si se ejecutan de manera asíncrona cuando el DOM (el árbol que contiene toda la lógica de las etiquetas HTML y que puede ser accedido y modificado mediante JavaScript) ya está cargado cualquier modificación en el mismo será visible.
¿Carga asíncrona o síncrona de librerías?
Esta es la clave. La principal razón de la existencia del flickering es el momento y el modo en que cargamos la librería JavaScript del producto en cuestión.
Síncrono significa que los datos son recibidos en bloques y la transmisión de ese dato es constante, el resultado es que la página no se renderiza hasta que todo el código este cargado.
Al contrario, asíncrono significa que la transmisión se realiza en bytes o caracteres y la transmisión no es constante. Así, el renderizado de elementos se produce una vez la página está cargada y visible.
A nivel de código es muy sencillo, basta incluir un parámetro en la etiqueta del script. Aquí un ejemplo de la carga de la librería Adobe Target en modo asíncrono:
<script async src=”at.js” <script> |
Las ventajas e inconvenientes de una u otra arquitectura las resumimos en esta tabla:
Carga Librerías |
Ventajas |
Desventajas |
Síncrona |
Flickering Cero |
Se puede ralentizar la página (o bloquearla en un caso extremo) |
Asíncrona |
Mayor seguridad a bloqueos por indisponibilidad de la librería JS |
Mayor lentitud a la hora de ejecutar las personalizaciones Peor experiencia de usuario en testing y personalizaciones si no se ponen medidas externas. |
Por lo general la decisión de usar una u otra aproximación compete a distintos departamentos. Normalmente IT y los responsables de SEO siempre preferirán la asíncrona y por parte de CRO preferiremos siempre la primera opción.
Implementación a través de Tag Manager
Al hilo de lo que acabamos de comentar de los tipos de carga de archivos, está la posibilidad de incluir las librerías de las diferentes herramientas de personalización mediante un Tag Management System (GTM, Adobe Launch, Tealium IQ,…).
En este caso lo normal es que la carga del propio Tag Manager se haga en modo asíncrono (aunque dependiendo del fabricante podemos encontrar las dos opciones de carga) ya que no queremos penalizar la carga de nuestras páginas para lanzar peticiones de analítica y pixels publicitarios.
Es decir, todo lo que hemos comentado anteriormente acerca de la carga de las librerías asíncronas se aplicaría a cuando lo hacemos a través de un Tag Manager.
El fragmento Anti-Flickering
Para facilitar la adopción de arquitecturas asíncronas casi todos los fabricantes incluyen en su documentación la posibilidad de incluir un fragmento de código JavaScript anti-flickering. Algunos ejemplos de estos códigos se pueden encontrar en las siguientes urls:
https://support.google.com/optimize/answer/7100284?hl=es
El comportamiento de todos estos snippets de código es similar: esconder el body unos segundos hasta que estén cargadas las librerías del producto de que se trate.
No resultan ser la solución definitiva al problema ya que, al hacer la ejecución asíncrona la carga de los archivos JavaScript se desprioriza y los cambios tardan más en ejecutarse que en modo síncrono. Esta situación hace que tengamos que ajustar muy bien esos tiempos de timeout de visibilidad del código que en muchas ocasiones van a ser sensiblemente superiores a cuando estamos ejecutando en modo síncrono.
La gestión del consentimiento
Además del modo en que carguemos las librerías de nuestro software de A/B testing y personalización algo que nos va a impactar a efectos de flickering es la gestión del consentimiento.
La nueva Guía de cookies de la AEPD entró en vigor el 31 de octubre de 2020 y se diferencia de su predecesora en que los muros de cookies que no ofrezcan una alternativa al consentimiento ya no están permitidos y el hecho de seguir navegando en una página web no se considera una forma válida de consentimiento.
La nueva normativa pretende reemplazar la versión anterior, de noviembre de 2019, con el fin de incorporar las recientes Directrices 05/2020 sobre consentimiento del Comité Europeo de Protección de Datos (CEPD).
Esto afecta a las cookies de las herramientas de personalización y, sin entrar a debatir, esto daría para un sólo artículo, si la interpretación de la AEPD sea demasiado estricta (no todos los casos son iguales ya que no es lo mismo un test A/B basado en una segmentación aleatoria que una personalización basada en atributos de cliente).
La necesidad de aceptación previa (aquí también influirá la interpretación que el departamento legal de cada organización dé a la normativa y el riesgo de una posible sanción que esté dispuesto a asumir) va a impactar en la performance de nuestros test ya que las peticiones de contenido a la herramienta van a quedar condicionadas a la aceptación previa de las cookies, con lo que cualquier modificación del contenido realizada en este contexto será visible para el usuario.
La mejor gestión de este “problema” la hemos encontrado en Oracle Maxymiser que tiene una configuración cookieless que permite ejecutar las personalizaciones sin grabar cookies (manteniendo los identificadores de usuario en variables) y una vez se produce la aceptación es cuando procede al guardado de los mismos en cookies.
https://docs.oracle.com/en/cloud/saas/marketing/maxymiser-developers-help/setup/cookie-consent.html
Esta opción nos solucionaría algunos casos de uso aunque, como la propia ayuda indica, puede impactar en el análisis estadístico de los resultados ya que cada “recarga” de una página sin aceptación de cookies de personalización nos generará un nuevo usuario en la herramienta.
No hemos visto ninguna otra arquitectura parecida en resto de fabricantes, con lo que la solución más habitual será diferir las peticiones de contenido hasta la prestación efectiva del consentimiento y tratar el flickering de la manera más creativa que se nos ocurra, usando transiciones lo más elegantes posible.
Conclusiones
En resumen, la mejor forma de evitar el flickering en nuestros experimentos pasa por la revisión de estos puntos:
- Cargar las librerías JS de la herramienta de testing al principio del head del documento
- Usar preferentemente la carga síncrona del archivo
- En el caso de usar la carga asíncrona, integrar en nuestras templates el fragmento antiflickering que nos proporcione el fabricante
Por último, para el caso de integración con consentimiento y dependiendo del escenario:
- Revisar la documentación del fabricante en busca de la mejor arquitectura de integración con CMPs (Consent Management Platforms)
- En caso de no tener más opción que hacer las modificaciones de contenido tras el consentimiento del usuario tratar de minimizar el efecto mediante el mejor uso de JavaScript y CSS que se nos ocurra para el caso en cuestión
Y, en todo caso, hay que revisar en detalle el código JavaScript que ejecutamos en cada experiencia ya que muchas veces la descarga y ejecución de este código será el causante de los problemas (aquí el número y complejidad de las personalizaciones tiene un peso crucial).
Si después de seguir estas recomendaciones seguimos padeciendo el temido efecto, hay que revisar muy en detalle cada una de los casos de uso, las templates afectadas y cómo se produce la carga de contenidos y el renderizado porque a veces no hay una única solución a todos los problemas y deberemos adaptar la implementación para que cubra la mayor parte de casuísticas.
Como podemos observar, cada opción de implementación en cliente tiene sus fortalezas y debilidades. Por este motivo, la implementación en el lado del servidor (en algunos casos) será la mejor solución.