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

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

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

בטי קרוקר (Betty Crocker), שהושקו לאחרונה בהרבה מעריצים, הוציאו לאחרונה את האפליקציות שלה מ-Apple App Store ומחנות Google Play אחרי שקיבלו עדיפות. במשך תקופה ארוכה, הצוות של בטי קרוקר העדיף להוסיף תכונות חדשות לאתר לנייד במקום לאפליקציות ל-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) והפעלת המתג מניעת החשכה של המסך בזמן הבישול.

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

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

תודות

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