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

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

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

האפליקציות של Betty Crocker הושקו ברעש גדול בשנת 2014, אבל לאחרונה הן הוסרו מחנות האפליקציות של אפל ומחנות 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.

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

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

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

כדי לבקש חסימה של מצב שינה, צריך להפעיל את 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% הפעילו את התכונה באופן מיידי, והיא נכנסה לרשימת 5 הפעולות המובילות.
  • משך הסשן של משתמשים שהפעילו את ההגדרה 'מניעת מעבר למצב שינה' היה ארוך פי 3.1 ממשך הסשן של משתמשים שלא הפעילו אותה.
  • שיעור הנטישה של משתמשים שהפעילו את נעילת ההשכמה היה נמוך ב-50% מזה של משתמשים שלא השתמשו בתכונה הזו.
  • האינדיקטורים של כוונת רכישה היו גבוהים בכ-300% בקרב משתמשים שהשתמשו ב-wake lock בהשוואה לכל המשתמשים.

‫3.1×

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

‫50%

שיעור עזיבה נמוך יותר

‫300%

אינדיקטורים חזקים יותר של כוונת רכישה

מסקנות

חברת Betty Crocker השיגה תוצאות מעולות באמצעות Wake Lock API. אתם יכולים לבדוק את התכונה בעצמכם: חפשו מתכון שאתם אוהבים באחד מהאתרים האלה (BettyCrocker,‏ Pillsbury או Tablespoon) והפעילו את המתג מניעת החשכת המסך בזמן הבישול.

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

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