Wake Lock API 個案研究:BettyCrocker.com 上的購買意願指標提升了 300%

使用行動裝置烹飪時,最糟糕的情況莫過於在食譜步驟中途螢幕關閉。瞭解烹飪網站 BettyCrocker.com 如何使用 Wake Lock API 避免發生這種情況。

近一個世紀以來,Betty Crocker 一直是美國現代烹飪教學和可靠食譜開發的來源。該公司在 1997 年推出的網站 BettyCrocker.com,目前每月吸引超過 1, 200 萬名訪客造訪。實作 Wake Lock API 後,與所有使用者相比,喚醒鎖定使用者的購買意圖指標提升了約 300%

Betty Crocker 於 2014 年推出的應用程式廣受歡迎,但最近因應用程式優先順序降低,因此將其從 Apple App Store 和 Google Play 商店下架。長期以來,Betty Crocker 團隊都偏好在行動網站中加入新功能,而不是在 iOS/Android 應用程式中加入。建立 iOS/Android 應用程式的技術平台已過時,且該企業沒有資源支援應用程式的更新和維護作業。從流量角度來看,網頁應用程式也更有優勢,因為它更現代化,也更容易強化。

不過,iOS/Android 應用程式確實有一個使用者喜愛的殺手功能

千禧世代烹飪專家提示:@BettyCrocker 行動應用程式在你按照食譜操作時,不會調低亮度或鎖定。—@AvaBeilke

80% 的使用者會在廚房中使用裝置烹飪,但螢幕調暗和鎖定功能仍有問題。@BettyCrocker 做了什麼?更新應用程式,讓使用者在食譜中瀏覽時不會變暗。—@KatieTweedy

使用 Wake Lock API 為網路帶來強大功能

使用裝置烹飪時,最令人沮喪的莫過於在螢幕關閉時,必須用髒手或鼻子觸碰螢幕。Betty Crocker 想知道如何將 iOS/Android 應用程式的絕佳功能移植到網路應用程式。這時,她瞭解了 Project FuguWake Lock API

有人在廚房的桌上揉麵團,桌上有麵粉

Wake Lock API 提供一種方法,可防止裝置調低亮度或鎖定螢幕。這項功能可提供全新體驗,而這類體驗先前必須透過 iOS/Android 應用程式才能使用。Wake Lock API 可減少使用者需要使用不正當且可能耗電的因應措施。

要求 Wake Lock

如要要求喚醒鎖定,您必須呼叫會傳回 WakeLockSentinel 物件的 navigator.wakeLock.request() 方法。您會將這個物件用做哨值值。瀏覽器可能會基於各種原因 (例如電池電量過低) 拒絕要求,因此建議您在 try…catch 陳述式中包裝呼叫。

釋放 Wake Lock

您還需要一種釋放喚醒鎖定的方法,方法是呼叫 WakeLockSentinel 物件的 release() 方法。如果您想在一段時間過後自動釋放喚醒鎖定,可以使用 window.setTimeout() 呼叫 release(),如以下範例所示。

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

實作

有了新的網頁應用程式,使用者就能輕鬆瀏覽食譜、完成步驟,甚至離開螢幕也不會鎖定。為達成這個目標,團隊首先快速建構前端原型,做為概念驗證,並收集使用者體驗相關意見。

原型證明實用後,他們設計了一個Vue.js 元件,可供所有品牌 (BettyCrockerPillsburyTablespoon) 共用。雖然只有 Betty Crocker 有 iOS 和 Android 應用程式,但這三個網站確實有共用的程式碼集,因此可以實作一次元件,然後在所有地方部署,如以下螢幕截圖所示。

BettyCrocker.com Wake Lock 切換鈕
BettyCrocker.com 喚醒鎖定切換鈕。
Pillsbury.com Wake Lock 切換鈕
Pillsbury.com 喚醒鎖定切換鈕。
Tablespoon.com Wake Lock 切換鈕
Tablespoon.com Wake Lock 切換鈕。

在根據新網站的現代化架構開發元件時,我們特別著重於 MVVM 模式的 ViewModel。團隊也考量到互通性而進行程式設計,以便在網站的舊版和新版架構中啟用功能。

為了追蹤可視度和可用性,Betty Crocker 整合了喚醒鎖定生命週期中核心事件的數據分析追蹤功能。團隊利用功能管理功能,將喚醒鎖定元件部署到單一網站,以便進行初始正式版推出作業,然後在監控使用情形和網頁健康狀況後,將該功能部署到其他網站。並根據這個元件的使用情形,持續監控數據分析資料。

為確保使用者安全,團隊建立了強制逾時機制,在閒置一小時後停用喚醒鎖定機制。他們最終決定在短期內,在網站上的所有食譜頁面中加入切換鈕。他們希望長期能推出新版食譜頁面。

Wake Lock 容器

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

喚醒鎖定元件

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

結果

Vue.js 元件已部署在所有三個網站上,並帶來出色的成效。在 2019 年 12 月 10 日至 2020 年 1 月 10 日期間,BettyCrocker.com 回報了以下指標:

  • 在 Betty Crocker 使用者中,有 3.5% 使用者使用與 Wake Lock API 相容的瀏覽器,並立即啟用這項功能,因此這項功能成為前 5 大操作。
  • 啟用喚醒鎖定功能的使用者的工作階段時間比未啟用的使用者長 3.1 倍。
  • 啟用喚醒鎖定功能的使用者,其跳出率比未使用喚醒鎖定功能的使用者低 50%。
  • 與所有使用者相比,喚醒鎖定使用者的購買意願指標高出約 300%。

3.1×

工作階段持續時間更長

50%

跳出率降低

300%

購買意願指標較高

結論

Betty Crocker 使用 Wake Lock API 獲得了出色的成果。你可以自行測試這項功能,只要在任何網站 (BettyCrockerPillsburyTablespoon) 搜尋喜愛的食譜,然後啟用「烹飪時避免螢幕變暗」切換鈕即可。

喚醒鎖的用途不只限於食譜網站。其他例子包括登機證或票證應用程式,需要在掃描條碼前保持螢幕開啟;自助式應用程式,需要持續保持螢幕開啟;或以網頁為主的簡報應用程式,需要在簡報期間防止螢幕進入休眠狀態。

我們已在本網站上撰寫一篇全面性的文章,彙整了您需要瞭解的所有 Wake Lock API 相關資訊。祝你閱讀愉快,烹飪愉快!

特別銘謝

人物揉麵相片Julian Hochgesang 提供,取自 Unsplash