Étude de cas sur l'API Wake Lock: augmentation de 300% des indicateurs d'intention d'achat sur BettyCrocker.com

Rien n'est pire, lorsque vous cuisinez avec un appareil mobile, que son écran qui s'éteint au milieu d'une étape de la recette. Découvrez comment le site de cuisine BettyCrocker.com a utilisé l'API Wake Lock pour éviter cela.

Depuis près d'un siècle, Betty Crocker est la source américaine d'instructions de cuisine modernes et de recettes fiables. Lancé en 1997, son site BettyCrocker.com reçoit aujourd'hui plus de 12 millions de visiteurs par mois. Après avoir implémenté l'API Wake Lock, leurs indicateurs d'intention d'achat ont augmenté d'environ 300% pour les utilisateurs de wake lock par rapport à tous les utilisateurs.

Applications iOS et Android obsolètes

Lancées avec beaucoup de fanfare en 2014, les applications Betty Crocker ont récemment été retirées de l'App Store d'Apple et du Google Play Store après avoir été dépriorisées. Depuis longtemps, l'équipe Betty Crocker préfère ajouter de nouvelles fonctionnalités au site mobile plutôt qu'aux applications iOS/Android. La plate-forme technique sur laquelle les applications iOS/Android ont été créées était obsolète, et l'entreprise ne disposait pas des ressources nécessaires pour mettre à jour et gérer les applications à l'avenir. L'application Web était également objectivement beaucoup plus importante en termes de trafic, plus moderne et plus facile à améliorer.

Les applications iOS/Android disposaient toutefois d'une fonctionnalité de pointe que leurs utilisateurs adoraient:

Conseil d'expert culinaire pour les millennials: l'application mobile @BettyCrocker ne s'éteint pas et ne se verrouille pas lorsque vous suivez une recette. —@AvaBeilke

80% des personnes cuisinent avec un appareil dans la cuisine, mais le verrouillage et l'assombrissement de l'écran pose problème. Que fait @BettyCrocker ? Mise à jour de l'application pour qu'elle ne s'assombrisse pas lorsque les utilisateurs sont dans une recette. —@KatieTweedy

Proposer la fonctionnalité phare sur le Web avec l'API Wake Lock

Lorsque vous cuisinez avec un appareil, rien n'est plus frustrant que d'avoir à toucher l'écran avec des mains sales ou même avec le nez lorsque l'écran s'éteint. Betty Crocker s'est demandé comment porter la fonctionnalité phare de ses applications iOS/Android vers l'application Web. C'est alors qu'elle a découvert le projet Fugu et l'API Wake Lock.

Une personne pétrit de la pâte sur une table de cuisine recouverte de farine.

L'API Wake Lock permet d'empêcher l'appareil de réduire la luminosité ou de verrouiller l'écran. Cette fonctionnalité permet de proposer de nouvelles expériences qui, jusqu'à présent, nécessitaient une application iOS/Android. L'API Wake Lock réduit le besoin de solutions de contournement peu fiables et potentiellement gourmandes en énergie.

Demander un wakelock

Pour demander un verrouillage de réveil, vous devez appeler la méthode navigator.wakeLock.request() qui renvoie un objet WakeLockSentinel. Vous utiliserez cet objet comme valeur sentinelle. Le navigateur peut refuser la requête pour diverses raisons (par exemple, si la batterie est trop faible). Il est donc recommandé d'encapsuler l'appel dans une instruction try…catch.

Libérer un wakelock

Vous devez également disposer d'un moyen de libérer un verrouillage de réveil, ce qui se fait en appelant la méthode release() de l'objet WakeLockSentinel. Si vous souhaitez libérer automatiquement le verrouillage de réveil après un certain temps, vous pouvez utiliser window.setTimeout() pour appeler release(), comme illustré dans l'exemple ci-dessous.

// 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);

L'implémentation

Avec la nouvelle application Web, les utilisateurs doivent pouvoir naviguer facilement dans une recette, suivre les étapes et même s'éloigner sans que l'écran ne se verrouille. Pour atteindre cet objectif, l'équipe a d'abord créé un prototype front-end rapide à titre de preuve de concept et pour recueillir des commentaires sur l'expérience utilisateur.

Une fois que le prototype s'est avéré utile, ils ont conçu un composant Vue.js pouvant être partagé entre toutes leurs marques (BettyCrocker, Pillsbury et Tablespoon). Même si seule Betty Crocker proposait des applications iOS et Android, les trois sites disposent d'un codebase partagé. Ils ont donc pu implémenter le composant une seule fois et le déployer partout, comme illustré dans les captures d'écran ci-dessous.

Boutons d'activation/de désactivation du wakelock BettyCrocker.com
BettyCrocker.com wake lock toggle.
Bouton d'activation/de désactivation du wakelock sur Pillsbury.com
Boutons d'activation/de désactivation du wakelock sur Pillsbury.com
Bouton d'activation/de désactivation du wakelock Tablespoon.com
Boutons d'activation/de désactivation du wakelock de Spoon.com.

Lors du développement du composant basé sur le framework modernisé du nouveau site, l'accent a été mis sur la couche ViewModel du modèle MVVM. L'équipe a également programmé en tenant compte de l'interopérabilité pour permettre le fonctionnement des anciens et nouveaux frameworks du site.

Pour suivre la visibilité et la facilité d'utilisation, Betty Crocker a intégré le suivi des données analytiques pour les événements principaux du cycle de vie du verrouillage de réveil. L'équipe a utilisé la gestion des fonctionnalités pour déployer le composant de verrouillage de réveil sur un seul site pour le déploiement initial en production, puis a déployé la fonctionnalité sur le reste des sites après avoir surveillé l'utilisation et l'état des pages. Ils continuent de surveiller les données analytiques en fonction de l'utilisation de ce composant.

Pour éviter les défaillances, l'équipe a créé un délai avant expiration forcé pour désactiver le verrouillage de réveil après une heure d'inactivité. L'implémentation finale sur laquelle ils se sont arrêtés à court terme a consisté en un bouton d'activation/de désactivation sur toutes les pages de recettes de leurs sites. À long terme, il envisage de remanier la vue de la page des recettes.

Conteneur de wakelock

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');
      }
    },
  },
};

Composant Wakelock

<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>

Résultats

Le composant Vue.js a été déployé sur les trois sites et a donné d'excellents résultats. Entre le 10 décembre 2019 et le 10 janvier 2020, BettyCrocker.com a enregistré les métriques suivantes:

  • Parmi tous les utilisateurs de Betty Crocker disposant d'un navigateur compatible avec l'API Wake Lock, 3,5% d'entre eux ont activé immédiatement cette fonctionnalité, ce qui la place dans le top 5 des actions.
  • La durée de la session pour les utilisateurs qui ont activé le verrouillage de réveil était 3,1 fois plus longue que pour ceux qui ne l'ont pas fait.
  • Le taux de rebond des utilisateurs qui ont activé le verrouillage de réveil était 50% inférieur à celui de ceux qui n'utilisaient pas cette fonctionnalité.
  • Les indicateurs d'intention d'achat étaient environ 300% plus élevés pour les utilisateurs de wake lock que pour tous les utilisateurs.

3.1×

Durée de session plus longue

50 %

de baisse du taux de rebond

300 %

Indicateurs d'intention d'achat plus élevés

Conclusions

Betty Crocker a obtenu des résultats fantastiques grâce à l'API Wake Lock. Vous pouvez tester cette fonctionnalité vous-même en recherchant votre recette préférée sur l'un de leurs sites (BettyCrocker, Pillsbury ou Tablespoon) et en activant l'option Empêcher l'écran de s'éteindre pendant la cuisson.

Les cas d'utilisation des réveils ne se limitent pas aux sites de recettes. Il peut également s'agir d'applications de carte d'embarquement ou de billet qui doivent maintenir l'écran allumé jusqu'à ce que le code-barres ait été scanné, d'applications de type borne qui maintiennent l'écran allumé en permanence ou d'applications de présentation Web qui empêchent l'écran de se mettre en veille pendant une présentation.

Nous avons compilé tout ce que vous devez savoir sur l'API Wake Lock dans un article complet sur ce site. Bonne lecture et bon appétit !

Remerciements

Photo de la personne pétrissant de la pâte, fournie par Julian Hochgesang sur Unsplash.