Case study sull'API Wake Lock: aumento del 300% degli indicatori dell'intenzione di acquisto su BettyCrocker.com

Non c'è niente di peggio quando cucini con un dispositivo mobile rispetto allo spegnimento dello schermo nel bel mezzo di un passaggio della ricetta. Scopri come il sito di ricette BettyCrocker.com ha utilizzato l'API Wake Lock per evitare che ciò accada.

Da quasi un secolo, Betty Crocker è la fonte di riferimento per le istruzioni di cucina moderne e per lo sviluppo di ricette affidabili negli Stati Uniti. Lanciato nel 1997, il sito BettyCrocker.com oggi riceve più di 12 milioni di visitatori al mese. Dopo aver implementato l'API Wake Lock, i loro indicatori di intenzione di acquisto erano circa il 300% più elevati per gli utenti con blocco schermo attivo rispetto a tutti gli utenti.

Le app per iOS e Android ritirate

Lanciata nel 2014 con grande fanfara, Betty Crocker ha recentemente ritirato le sue app dall'Apple App Store e dal Google Play Store dopo che sono state riassegnate a una priorità inferiore. Per molto tempo, il team di Betty Crocker ha preferito aggiungere nuove funzionalità al sito mobile anziché alle app per iOS/Android. La piattaforma tecnica su cui sono state create le app per iOS/Android era obsoleta e l'azienda non aveva le risorse per supportare l'aggiornamento e la manutenzione delle app in futuro. Inoltre, l'app web aveva un traffico oggettivamente molto più elevato, era più moderna e più facile da migliorare.

Le app per iOS/Android avevano però una funzionalità vincente, molto apprezzata dagli utenti:

Suggerimento per i millennial che amano cucinare: l'app mobile @BettyCrocker non si attenua né si blocca quando segui una ricetta. -@AvaBeilke

L'80% delle persone cucina con un dispositivo in cucina, ma il problema è la regolazione della luminosità e il blocco dello schermo. Che cosa ha fatto @BettyCrocker? Ha aggiornato l'app in modo che NON si attenua quando gli utenti sono in una ricetta. -@KatieTweedy

Portare la funzionalità più importante sul web con l'API Wake Lock

Quando cucini con un dispositivo, non c'è niente di più frustrante di dover toccare lo schermo con le mani sporche o persino con il naso quando lo schermo si spegne. Betty Crocker si è chiesta come poter trasferire la funzionalità più importante delle sue app per iOS/Android all'app web. È stato allora che ha scoperto Project Fugu e l'API Wake Lock.

Una persona che impasta l'impasto su un tavolo da cucina coperto di farina

L'API Wake Lock fornisce un modo per impedire al dispositivo di attenuare o bloccare lo schermo. Questa funzionalità consente nuove esperienze che, finora, richiedevano un'app per iOS/Android. L'API Wake Lock riduce la necessità di soluzioni alternative poco sicure e potenzialmente dispendiose in termini di energia.

Richiesta di un blocco di attivazione

Per richiedere un blocco di attivazione, devi chiamare il metodo navigator.wakeLock.request() che restituisce un oggetto WakeLockSentinel. Utilizzerai questo oggetto come valore sentinella. Il browser può rifiutare la richiesta per vari motivi (ad esempio perché la batteria è troppo scarica), quindi è buona norma racchiudere la chiamata in un'istruzione try…catch.

Rilasciare un wakelock

Inoltre, devi avere un modo per rilasciare un blocco sveglia, che viene ottenuto chiamando il metodo release() dell'oggetto WakeLockSentinel. Se vuoi rilasciare automaticamente il blocco di attivazione dopo un determinato periodo di tempo, puoi utilizzare window.setTimeout() per chiamare release(), come mostrato nell'esempio seguente.

// 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'implementazione

Con la nuova app web, gli utenti dovrebbero essere in grado di navigare facilmente tra le ricette, completare i passaggi e persino allontanarsi senza che lo schermo si blocchi. Per raggiungere questo obiettivo, il team ha inizialmente creato un rapido prototipo di front-end come proof of concept e per raccogliere input sull'esperienza utente.

Dopo che il prototipo si è dimostrato utile, hanno progettato un componente Vue.js che poteva essere condiviso tra tutti i loro brand (BettyCrocker, Pillsbury e Tablespoon). Anche se solo Betty Crocker aveva app per iOS e Android, i tre siti condividono una base di codice, quindi è stato possibile implementare il componente una volta sola e implementarlo ovunque, come mostrato negli screenshot di seguito.

Pulsante di attivazione/disattivazione del wakelock di BettyCrocker.com
Blocco attivazione BettyCrocker.com.
Pulsante di attivazione/disattivazione del wakelock di Pillsbury.com
Blocco attivazione/disattivazione di Pillsbury.com
.
Pulsante di attivazione/disattivazione del wakelock di Tablespoon.com
Opzione di attivazione/disattivazione del wakelock di Tablespoon.com.

Durante lo sviluppo del componente basato sul framework modernizzato del nuovo sito, abbiamo dato molta importanza al livello ViewModel del pattern MVVM. Il team ha anche programmato tenendo presente l'interoperabilità per attivare la funzionalità nei framework precedenti e nuovi del sito.

Per tenere traccia della visibilità e dell'usabilità, Betty Crocker ha integrato il monitoraggio di Dati per gli eventi principali nel ciclo di vita del blocco sveglia. Il team ha utilizzato la gestione delle funzionalità per implementare il componente di blocco risveglio su un singolo sito per l'implementazione iniziale in produzione, quindi ha implementato la funzionalità nel resto dei siti dopo aver monitorato l'utilizzo e l'integrità delle pagine. Continuano a monitorare i dati di analisi in base all'utilizzo di questo componente.

Come misura di sicurezza per gli utenti, il team ha creato un timeout forzato per disattivare il blocco sveglia dopo un'ora di inattività. L'implementazione finale che ha scelto è stata, a breve termine, un pulsante di attivazione/disattivazione su tutte le pagine delle ricette dei suoi siti. A lungo termine, prevedono di rinnovare la visualizzazione della pagina delle ricette.

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

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

Risultati

Il componente Vue.js è stato implementato su tutti e tre i siti e ha generato ottimi risultati. Nel periodo compreso tra il 10 dicembre 2019 e il 10 gennaio 2020, BettyCrocker.com ha registrato le seguenti metriche:

  • Di tutti gli utenti di Betty Crocker con un browser compatibile con l'API Wake Lock, il 3,5% ha attivato immediatamente la funzionalità, rendendola una delle prime cinque azioni.
  • La durata della sessione per gli utenti che hanno attivato il blocco di attivazione è stata 3,1 volte superiore rispetto a quella degli utenti che non l'hanno fatto.
  • Il tasso di abbandono degli utenti che hanno attivato il blocco schermo è stato inferiore del 50% rispetto a quello degli utenti che non utilizzano la funzionalità.
  • Gli indicatori di intenzione di acquisto erano circa il 300% più elevati per gli utenti con blocco schermo attivo rispetto a tutti gli utenti.

3.1×

Durata della sessione più lunga

50%

Frequenza di rimbalzo inferiore

300%

Indicatori di intenzione di acquisto più elevata

Conclusioni

Betty Crocker ha ottenuto risultati fantastici utilizzando l'API Wake Lock. Puoi testare la funzionalità cercando la tua ricetta preferita su uno dei loro siti (BettyCrocker, Pillsbury o Tablespoon) e attivando l'opzione Impedisci lo spegnimento dello schermo durante la cottura.

I casi d'uso per i blocchi di riattivazione non si limitano ai siti di ricette. Altri esempi sono le app per tessere di imbarco o biglietti che devono mantenere lo schermo attivo fino alla scansione del codice a barre, le app in stile chiosco che mantengono lo schermo attivo continuamente o le app di presentazione basate su web che impediscono lo spegnimento dello schermo durante una presentazione.

Abbiamo raccolto tutto ciò che devi sapere sull'API Wake Lock in un articolo esaustivo su questo stesso sito. Buona lettura e buon appetito!

Ringraziamenti

La foto della persona che impasta l'impasto è di Julian Hochgesang su Unsplash.