מקרה לדוגמה של Wake Lock API: עלייה של 300% באינדיקטורים של כוונת רכישה באתר BettyCrocker.com

אין דבר גרוע יותר כשמבשלים עם מכשיר נייד מאשר שהמסך שלו נכבה באמצע שלב במתכון. בקישור הבא אפשר לקרוא איך אתר הבישול BettyCrocker.com השתמש ב-Wake Lock API כדי למנוע מצב כזה.

במשך כמעט מאה שנה, Betty Crocker היא המקור האמריקאי להוראות בישול מודרניות ולפיתוח מתכונים מהימנים. האתר BettyCrocker.com הושק בשנת 1997, וכיום מגיעים אליו יותר מ-12 מיליון מבקרים בחודש. אחרי שהם הטמיעו את Wake Lock API, האינדיקטורים של כוונת הרכישה היו גבוהים ב-300% בקרב משתמשים עם Wake Lock בהשוואה לכל המשתמשים.

האפליקציות ל-iOS ול-Android שהוצאו משימוש

לאחר השקת האפליקציות של Betty Crocker ב-2014 ברעש רב, החברה הפסיקה לאחרונה להציג אותן בחנות האפליקציות של Apple ובחנות Google Play, אחרי שהן הוצאו מרשימת האפליקציות בעדיפות גבוהה. במשך זמן רב, צוות Betty Crocker העדיף להוסיף תכונות חדשות לאתר לנייד במקום לאפליקציות ל-iOS או ל-Android. הפלטפורמה הטכנית שבה נוצרו האפליקציות ל-iOS ול-Android הייתה מיושנת, ולא היו לעסק המשאבים הנדרשים כדי לעדכן ולתחזק את האפליקציות בהמשך. בנוסף, אפליקציית האינטרנט נהנתה מנפח תנועה גדול יותר באופן אובייקטיבי, הייתה מודרנית יותר וקלה יותר לשיפור.

עם זאת, לאפליקציות ל-iOS ול-Android הייתה תכונה פופולרית אחת שהמשתמשים אהבו:

טיפ למיליניאלים בתחום הבישול: האפליקציה לנייד של @BettyCrocker לא מתעממת או ננעלת כשאתם מבצעים מתכון. —‎@AvaBeilke

80% מהאנשים מבשלים עם מכשיר במטבח, אבל האפלה ונעילה של המסך הם בעיה. מה @BettyCrocker עשתה? עדכנו את האפליקציה שלהם כך שהיא לא תדעך כשמשתמשים נמצאים במתכון. —@KatieTweedy

הוספת התכונה המיוחדת הזו לאינטרנט באמצעות Wake Lock API

כשאתם מבשלים במכשיר, אין דבר מתסכל יותר מלגעת במסך עם ידיים מלוכלכות או אפילו עם האף כשהמסך כבוי. ב-Betty Crocker שאלו את עצמם איך הם יכולים להעביר את התכונה המיוחדת של האפליקציות שלהם ל-iOS ול-Android לאפליקציית האינטרנט. אז הם למדו על Project Fugu ועל Wake Lock API.

אדם ששואב בצק על שולחן מטבח מכוסה בקמח

Wake Lock API מספק דרך למנוע מהמכשיר לעמעם או לנעול את המסך. היכולת הזו מאפשרת חוויות חדשות שעד עכשיו נדרשה להן אפליקציה ל-iOS או ל-Android.‏ Wake Lock API מפחית את הצורך בדרכים חלופיות לא יעילות שצורכות הרבה חשמל.

שליחת בקשה לחסימת מצב שינה

כדי לבקש נעילת התעוררות, צריך לבצע קריאה ל-method‏ navigator.wakeLock.request() שמחזיר אובייקט WakeLockSentinel. תשתמשו באובייקט הזה בתור ערך סינון. הדפדפן יכול לדחות את הבקשה מסיבות שונות (למשל, כי רמת הטעינה של הסוללה נמוכה מדי), ולכן מומלץ לעטוף את הקריאה בהצהרה try…catch.

שחרור של חסימת מצב שינה

צריך גם דרך לשחרר את נעילת ההתעוררות, ואפשר לעשות זאת על ידי קריאה ל-method‏ release() של האובייקט WakeLockSentinel. אם רוצים לשחרר את נעילת ההתעוררות באופן אוטומטי אחרי פרק זמן מסוים, אפשר להשתמש ב-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 שאפשר לשתף עם כל המותגים שלהם (BettyCrocker,‏ Pillsbury ו-Tablespoon). למרות של-Betty Crocker היו אפליקציות ל-iOS ול-Android בלבד, לשלושת האתרים יש בסיס קוד משותף, כך שהם יכלו להטמיע את הרכיב פעם אחת ולפרוס אותו בכל מקום, כפי שמוצג בצילומי המסך שבהמשך.

מתג חסימת מצב שינה של BettyCrocker.com
מתג חסימת מצב שינה של BettyCrocker.com
מתג חסימת מצב שינה של Pillsbury.com
מתג ההפעלה/השבתה של נעילת ההתעוררות ב-Pillsbury.com
מתג חסימת מצב שינה של Tablespoon.com
מתג חסימת מצב שינה של Tablespoon.com

כשפיתחנו את הרכיב על סמך המסגרת המודרנית של האתר החדש, התמקדנו בשכבה ViewModel של תבנית MVVM. הצוות גם כתב את הקוד כך שיהיה תואם לשימוש במסגרות הקודמות והחדשות של האתר.

כדי לעקוב אחרי ניראות השימושיות, ב-Betty Crocker שילבו מעקב ניתוח נתונים של אירועים מרכזיים במחזור החיים של נעילת ההתעוררות. הצוות השתמש בניהול פיצ'רים כדי לפרוס את הרכיב של נעילת ההתעוררות לאתר אחד להשקה הראשונית בסביבת הייצור, ולאחר מכן פרס את התכונה בשאר האתרים אחרי מעקב אחר השימוש וסטטוס הדף. הם ממשיכים לעקוב אחרי נתוני ניתוח הנתונים על סמך השימוש ברכיב הזה.

כדי למנוע מצב של כשל אצל המשתמשים, הצוות יצר זמן קצוב לתפוגה מאולץ כדי להשבית את נעילת ההתעוררות אחרי שעה של חוסר פעילות. ההטמעה הסופית שהם בחרו לטווח הקצר היא מתג החלפת מצב בכל דפי המתכונים באתרים שלהם. בטווח הארוך, הם מתכננים לשפר את תצוגת דף המתכון.

מאגר חסימת מצב שינה

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 נפרס בכל שלושת האתרים והניב תוצאות מצוינות. בתקופה שבין 10 בדצמבר 2019 ל-10 בינואר 2020, האתר BettyCrocker.com דיווח על המדדים הבאים:

  • מתוך כל המשתמשים ב-Betty Crocker שיש להם דפדפן תואם ל-Wake Lock API, 3.5% מהם הפעילו את התכונה באופן מיידי, מה שהפך אותה לאחת מחמש הפעולות המובילות.
  • משך הסשן של משתמשים שהפעילו את נעילת ההתעוררות היה ארוך פי 3.1 ממשך הסשן של משתמשים שלא הפעילו אותה.
  • שיעור העזיבה של משתמשים שהפעילו את נעילת ההתעוררות היה נמוך ב-50% מזה של משתמשים שלא השתמשו בתכונה הזו.
  • המדדים של כוונת הרכישה היו גבוהים ב-300% בקרב משתמשים עם נעילת ההתעוררות בהשוואה לכל המשתמשים.

3.1×

משך סשן ארוך יותר

50%

שיעור יציאה נמוך יותר

300%

אינדיקטורים גבוהים יותר של כוונת רכישה

מסקנות

ב-Betty Crocker ראו תוצאות מצוינות באמצעות Wake Lock API. אתם יכולים לבדוק את התכונה בעצמכם. לשם כך, חפשו את המתכון האהוב עליכם באחד מהאתרים שלהם (BettyCrocker, ‏ Pillsbury או Tablespoon) והפעילו את המתג Prevent your screen from going dark while you cook (מניעת החשכה של המסך בזמן הבישול).

תרחישים לדוגמה לנעילה להפעלה לא מסתכמים באתרי מתכונים. דוגמאות נוספות הן אפליקציות של כרטיסי עלייה למטוס או כרטיסים שצריך להשאיר את המסך דלוק עד לסריקה של הברקוד, אפליקציות בסגנון קיוסק ששומרות על המסך דלוק באופן קבוע או אפליקציות של מצגות מבוססות-אינטרנט שמונעות מהמסך להיכנס למצב שינה במהלך מצגת.

אספק לכם כל מה שצריך לדעת על Wake Lock API במאמר מקיף באתר הזה. קריאה נעימה ובישול מהנה!

תודות

התמונה של האדם שמכין בצק באדיבות Julian Hochgesang ב-Unsplash.