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

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

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

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

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

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

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

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

השקת הפיצ'ר הקטלני לאינטרנט באמצעות Wake Lock API

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

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

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

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

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

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

נדרשת גם דרך לשחרור המנעול ממצב שינה, שמתקבלת באמצעות קריאה לשיטה 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 וכף). למרות שרק לבטי קרוקר היו אפליקציות ל-iOS ול-Android, לשלושת האתרים יש בסיס קוד משותף, כך שהם יכלו להטמיע את הרכיב פעם אחת ולפרוס אותו בכל מקום, כפי שאפשר לראות בצילומי המסך שלמטה.

מתג לכיבוי מצב שינה ב-BettyCrocker.com
החלפת מצב של חסימת מצב שינה ב-BettyCrocker.com
.
מתג לכיבוי מצב שינה ב-Pllsbridge.com
החלפת המצב של נעילת מצב השינה ב-Pills Cookie.com
מתג לחסימות מצב שינה ב-Tablepoon.com
החלפת המצב של חסימת מצב שינה ב-Tablespoon.com
.

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

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

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

המאגר של התכונה 'נעילת מצב שינה'

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% בקרב משתמשים שהפעילו את התכונה 'נעילת מצב שינה' בהשוואה לכל המשתמשים.

3.1×

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

50%

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

300%

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

מסקנות

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

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

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

אישורים

התמונה של האדם לישה לישה באדיבות יוליאן הוכגסאנג ב-Un אימיילים.