Caso de éxito de la API de Wake Lock: 300% de aumento en los indicadores de intención de compra en BettyCrocker.com

Cuando se cocina con un dispositivo móvil, lo peor que puede pasar es que la pantalla se apague en medio de un paso de la receta. Descubre cómo el sitio de recetas BettyCrocker.com usó la API de Wake Lock para evitar que esto suceda.

Durante casi un siglo, Betty Crocker ha sido la fuente de Estados Unidos para la instrucción de cocina moderna y el desarrollo de recetas confiables. Su sitio BettyCrocker.com, que se lanzó en 1997, hoy recibe más de 12 millones de visitantes por mes. Después de implementar la API de Wake Lock, sus indicadores de intención de compra fueron alrededor de un 300% más altos para los usuarios de Wake Lock en comparación con todos los usuarios.

Las apps para iOS y Android que dejaron de estar disponibles

Betty Crocker, que se lanzó con mucha fanfarria en 2014, quitó recientemente sus apps de la App Store de Apple y Google Play Store después de que se les quitara la prioridad. Durante mucho tiempo, el equipo de Betty Crocker prefirió agregar funciones nuevas al sitio para dispositivos móviles en lugar de las apps para iOS y Android. La plataforma técnica en la que se crearon las apps para iOS y Android estaba desactualizada, y la empresa no tenía los recursos para actualizar y mantener las apps en el futuro. La app web también era objetivamente mucho más grande en términos de tráfico, más moderna y más fácil de mejorar.

Sin embargo, las apps para iOS y Android tenían una función increíble que a los usuarios les encantó:

Sugerencia profesional para cocinar para millennials: La app para dispositivos móviles de @BettyCrocker no se atenúa ni se bloquea cuando sigues una receta. —@AvaBeilke

El 80% de las personas cocinan con un dispositivo en la cocina, pero el oscurecimiento y el bloqueo de la pantalla son un problema. ¿Qué hizo @BettyCrocker? Actualizó su app para que NO se atenúe cuando los usuarios están en una receta. —@KatieTweedy

Cómo llevar la función principal a la Web con la API de Wake Lock

Cuando se cocina con un dispositivo, nada es más frustrante que tener que tocar la pantalla con las manos sucias o incluso con la nariz cuando se apaga. Betty Crocker se preguntó cómo podría portar la función principal de sus apps para iOS y Android a la app web. Fue entonces cuando aprendió sobre el Project Fugu y la API de Wake Lock.

Una persona amasa masa en una mesa de cocina cubierta de harina

La API de Wake Lock proporciona una forma de evitar que el dispositivo atenúe o bloquee la pantalla. Esta función habilita nuevas experiencias que, hasta ahora, requerían una app para iOS o Android. La API de Wake Lock reduce la necesidad de soluciones alternativas hackeadas y potencialmente con mucho consumo de energía.

Cómo solicitar un bloqueo de activación

Para solicitar un bloqueo de activación, debes llamar al método navigator.wakeLock.request() que muestra un objeto WakeLockSentinel. Usarás este objeto como un valor centinela. El navegador puede rechazar la solicitud por varios motivos (por ejemplo, porque la batería está demasiado baja), por lo que se recomienda unir la llamada en una sentencia try…catch.

Cómo liberar un bloqueo de activación

También necesitas una forma de liberar un bloqueo de activación, que se logra llamando al método release() del objeto WakeLockSentinel. Si quieres liberar automáticamente el bloqueo de activación después de que haya transcurrido un período determinado, puedes usar window.setTimeout() para llamar a release(), como se muestra en el siguiente ejemplo.

// The wake lock sentinel.
let wakeLock = null;

// Function that attempts to request a wake lock.
const requestWakeLock = async () => {
  try {
    wakeLock = await navigator.wakeLock.request('screen');
    wakeLock.addEventListener('release', () => {
      console.log('Wake Lock was released');
    });
    console.log('Wake Lock is active');
  } catch (err) {
    console.error(`${err.name}, ${err.message}`);
  }
};

// Request a wake lock…
await requestWakeLock();
// …and release it again after 5s.
window.setTimeout(() => {
  wakeLock.release();
  wakeLock = null;
}, 5000);

La implementación

Con la nueva app web, los usuarios deberían poder navegar fácilmente por una receta, completar los pasos y hasta salir sin que se bloquee la pantalla. Para lograr este objetivo, el equipo primero creó un prototipo de frontend rápido como prueba de concepto y para recopilar entradas de UX.

Después de que el prototipo demostró ser útil, diseñaron un componente de Vue.js que se pudiera compartir en todas sus marcas (BettyCrocker, Pillsbury y Tablespoon). Aunque solo Betty Crocker tenía apps para iOS y Android, los tres sitios tienen una base de código compartida, por lo que pudieron implementar el componente una vez y, luego, implementarlo en todas partes, como se muestra en las capturas de pantalla que aparecen a continuación.

Activador del bloqueo de activación de BettyCrocker.com
Interruptor de bloqueo de activación de BettyCrocker.com.
Activador del bloqueo de activación de Pillsbury.com
Interruptor de bloqueo de activación de Pillsbury.com.
Activador de bloqueo de activación de Tablespoon.com
Interruptor de bloqueo de activación de Tablespoon.com.

Cuando se desarrolló el componente basado en el framework modernizado del sitio nuevo, se hizo un gran énfasis en la capa ViewModel del patrón MVVM. El equipo también programó teniendo en cuenta la interoperabilidad para habilitar la funcionalidad en los frameworks heredados y nuevos del sitio.

Para hacer un seguimiento de la visibilidad y la usabilidad, Betty Crocker integró el seguimiento de estadísticas para los eventos principales en el ciclo de vida del bloqueo de activación. El equipo usó la administración de funciones para implementar el componente de bloqueo de activación en un solo sitio para el lanzamiento inicial en producción y, luego, implementó la función en el resto de los sitios después de supervisar el uso y el estado de la página. Siguen supervisando los datos de estadísticas en función del uso de este componente.

Como medida de seguridad para los usuarios, el equipo creó un tiempo de espera forzoso para inhabilitar el bloqueo de activación después de una hora de inactividad. La implementación final que decidieron a corto plazo fue un botón de activación en todas las páginas de recetas de sus sitios. A largo plazo, prevén una vista de página de recetas renovada.

El contenedor de bloqueo de activación

var wakeLockControl = () => {
  return import(/* webpackChunkName: 'wakeLock' */ './wakeLock');
};

export default {
  components: {
    wakeLockControl: wakeLockControl,
  },
  data() {
    return {
      config: {},
      wakeLockComponent: '',
    };
  },
  methods: {
    init: function(config) {
      this.config = config || {};
      if ('wakeLock' in navigator && 'request' in navigator.wakeLock) {
        this.wakeLockComponent = 'wakeLockControl';
      } else {
        console.log('Browser not supported');
      }
    },
  },
};

El componente del bloqueo de activación

<template>
  <div class="wakeLock">
    <div class="textAbove"></div>
    <label class="switch" :aria-label="settingsInternal.textAbove">
      <input type="checkbox" @change="onChange()" v-model="isChecked">
      <span class="slider round"></span>
    </label>
  </div>
</template>

<script type="text/javascript">
  import debounce from 'lodash.debounce';

  const scrollDebounceMs = 1000;

  export default {
    props: {
      settings: { type: Object },
    },
    data() {
      return {
        settingsInternal: this.settings || {},
        isChecked: false,
        wakeLock: null,
        timerId: 0,
      };
    },
    created() {
      this.$_raiseAnalyticsEvent('Wake Lock Toggle Available');
    },
    methods: {
      onChange: function() {
        if (this.isChecked) {
          this.$_requestWakeLock();
        } else {
          this.$_releaseWakeLock();
        }
      },
      $_requestWakeLock: async function() {
        try {
          this.wakeLock = await navigator.wakeLock.request('screen');
          //Start new timer
          this.$_handleAbortTimer();
          //Only add event listeners after wake lock is successfully enabled
          document.addEventListener(
            'visibilitychange',
            this.$_handleVisibilityChange,
          );
          window.addEventListener(
            'scroll',
            debounce(this.$_handleAbortTimer, scrollDebounceMs),
          );
          this.$_raiseAnalyticsEvent('Wake Lock Toggle Enabled');
        } catch (e) {
          this.isChecked = false;
        }
      },
      $_releaseWakeLock: function() {
        try {
          this.wakeLock.release();
          this.wakeLock = null;
          //Clear timer
          this.$_handleAbortTimer();
          //Clean up event listeners
          document.removeEventListener(
            'visibilitychange',
            this.$_handleVisibilityChange,
          );
          window.removeEventListener(
            'scroll',
            debounce(this.$_handleAbortTimer, scrollDebounceMs),
          );
        } catch (e) {
          console.log(`Wake Lock Release Error: ${e.name}, ${e.message}`);
        }
      },
      $_handleAbortTimer: function() {
        //If there is an existing timer then clear it and set to zero
        if (this.timerId !== 0) {
          clearTimeout(this.timerId);
          this.timerId = 0;
        }
        //Start new timer; Will be triggered from toggle enabled or scroll event
        if (this.isChecked) {
          this.timerId = setTimeout(
            this.$_releaseWakeLock,
            this.settingsInternal.timeoutDurationMs,
          );
        }
      },
      $_handleVisibilityChange: function() {
        //Handle navigating away from page/tab
        if (this.isChecked) {
          this.$_releaseWakeLock();
          this.isChecked = false;
        }
      },
      $_raiseAnalyticsEvent: function(eventType) {
        let eventParams = {
          EventType: eventType,
          Position: window.location.pathname || '',
        };
        Analytics.raiseEvent(eventParams);
      },
    },
  };
</script>

Resultados

El componente Vue.js se implementó en los tres sitios y generó excelentes resultados. Durante el período del 10 de diciembre de 2019 al 10 de enero de 2020, BettyCrocker.com informó las siguientes métricas:

  • De todos los usuarios de Betty Crocker que tienen un navegador compatible con la API de Wake Lock, el 3.5% habilitó la función de inmediato, lo que la convierte en una de las 5 acciones principales.
  • La duración de la sesión de los usuarios que habilitaron el bloqueo de activación fue 3.1 veces más larga que la de los usuarios que no lo hicieron.
  • El porcentaje de rebote de los usuarios que habilitaron el bloqueo de activación fue un 50% más bajo que el de los que no usaban la función.
  • Los indicadores de intención de compra fueron alrededor de un 300% más altos para los usuarios de bloqueo de activación en comparación con todos los usuarios.

3.1×

Duración de la sesión más larga

50%

Porcentaje de rebote más bajo

300%

Indicadores de intención de compra más altos

Conclusiones

Betty Crocker obtuvo resultados fantásticos con la API de Wake Lock. Para probar la función, busca tu receta favorita en cualquiera de sus sitios (BettyCrocker, Pillsbury o Tablespoon) y habilita el botón de activación Evitar que la pantalla se oscurezca mientras cocinas.

Los casos de uso de los bloqueos de activación no se detienen en los sitios de recetas. Otros ejemplos son las apps de tarjetas de embarque o de boletos que deben mantener la pantalla encendida hasta que se escanea el código de barras, las apps de kiosco que mantienen la pantalla encendida de forma continua o las apps de presentación basadas en la Web que evitan que la pantalla entre en modo de suspensión durante una presentación.

Recopilamos todo lo que necesitas saber sobre la API de Wake Lock en un artículo completo en este mismo sitio. ¡Disfruta la lectura y la cocina!

Agradecimientos

La foto de la persona amasando masa es cortesía de Julian Hochgesang en Unsplash.