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

דייב גאש
דייב גאש
איליה גריגוריק
איליה גריגוריק

כותרת הבקשה לרמז לקוח של Save-Data הזמינה בדפדפני Chrome, Opera ו-Yandex, מאפשרת למפתחים לספק אפליקציות קלות ומהירות יותר למשתמשים שמסכימים למצב חיסכון בנתונים בדפדפן שלהם.

הצורך בדפים פשוטים

נתונים סטטיסטיים של Weblight

כולם מסכימים שדפי אינטרנט מהירים וקלים יותר מספקים חוויית משתמש טובה יותר, מספקים הבנה טובה יותר ושימור של התוכן ומשיגים יותר המרות והכנסות. ממחקר של Google עולה כי "...דפים שעברו אופטימיזציה נטענים במהירות גדולה פי ארבעה מהדף המקורי, והם משתמשים ב-80% פחות בייטים. מכיוון שהדפים האלה נטענים הרבה יותר מהר, ראינו גם עלייה של 50% בתנועה אל הדפים האלה."

ולמרות שמספר החיבורים ב-2G נמצא בסופו של דבר בירידה, ב-2015 עדיין הייתה טכנולוגיית הרשת הדומיננטית. שיעור חדירה וזמינות של רשתות 3G ו-4G הולך וגדל במהירות, אך עלויות הבעלות והמגבלות הנלוות לרשת עדיין מהווים גורם משמעותי עבור מאות מיליוני משתמשים.

אלה טיעונים חזקים לאופטימיזציה של דף.

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

כותרת הבקשה Save-Data

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

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

תמיכת דפדפן

מתבצע זיהוי של ההגדרה Save-Data

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

כשהמשתמש מפעיל את מצב החיסכון בנתונים בדפדפן, הדפדפן מצרף את כותרת הבקשה Save-Data לכל הבקשות היוצאות (גם ל-HTTP וגם ל-HTTPS). נכון למועד כתיבה זו, הדפדפן מפרסם רק אסימון *on אחד בכותרת (Save-Data: on), אך ייתכן כי בעתיד הוא יורחב כדי לציין העדפות של משתמשים אחרים.

בנוסף, יש אפשרות לזהות אם Save-Data מופעל ב-JavaScript:

if ('connection' in navigator) {
  if (navigator.connection.saveData === true) {
    // Implement data saving operations here.
  }
}

חשוב מאוד לבדוק אם האובייקט connection נמצא באובייקט navigator, כי הוא מייצג את Network Information API, שמוטמע רק בדפדפני האינטרנט Chrome, Chrome ל-Android ו-Samsung. משם צריך רק לבדוק אם navigator.connection.saveData שווה ל-true, ואפשר להטמיע את כל הפעולות של שמירת הנתונים בתנאי הזה.

הכותרת Save-Data מוצגת בכלים למפתחים ב-Chrome, יחד עם התוסף Data Saver.
הפעלת התוסף של חוסך הנתונים (Data Saver) ב-Chrome במחשב.

אם האפליקציה משתמשת ב-Service Worker, היא יכולה לבדוק את כותרות הבקשות ולהחיל לוגיקה רלוונטית כדי לשפר את החוויה. לחלופין, השרת יכול לחפש את ההעדפות שפורסמו בכותרת הבקשה Save-Data ולהחזיר תגובה חלופית – תגי עיצוב שונים, תמונות קטנות יותר וסרטונים קטנים יותר וכו'.

טיפים ושיטות מומלצות להטמעה

  1. כשמשתמשים ב-Save-Data, צריך לספק מספר מכשירים של ממשק המשתמש שתומכים בו ולאפשר למשתמשים לעבור בקלות בין חוויות. לדוגמה:
    • עליך להודיע למשתמשים על כך שהאפליקציה Save-Data נתמכת ולעודד אותם להשתמש בה.
    • המשתמשים יכולים לזהות ולבחור את המצב עם הנחיות מתאימות ולחצנים או תיבות סימון אינטואיטיביים להפעלה/השבתה.
    • כשבוחרים במצב חיסכון בחבילת הגלישה, יש דרך פשוטה וברורה להשבית אותו ולחזור לחוויה המלאה, אם רוצים.
  2. חשוב לזכור: יישומים קלים יותר אינם יישומים פחות טובים. הם לא משמיטים פונקציונליות או נתונים חשובים, הם פשוט מבינים יותר את העלויות הכרוכות ואת חוויית המשתמש. לדוגמה:
    • אפליקציה של גלריית תמונות עשויה לספק תצוגות מקדימות ברזולוציה נמוכה יותר, או להשתמש במנגנון קרוסלה פחות עמוס בקוד.
    • אפליקציית חיפוש עשויה להחזיר פחות תוצאות בכל פעם, להגביל את מספר התוצאות עם הרבה מדיה או לצמצם את מספר יחסי התלות הנדרשים לעיבוד הדף.
    • אתר שמתמקד בחדשות עשוי להציג פחות כתבות, להשמיט קטגוריות פחות פופולריות או להציג תצוגות מקדימות קטנות יותר של מדיה.
  3. חשוב לספק לוגיקה של השרת כדי לבדוק את כותרת הבקשה Save-Data, ולשקול לספק תגובת דף חלופית וקלה יותר כשמפעילים אותה – למשל, צמצום מספר המשאבים ויחסי התלות הנדרשים, דחיסת משאבים אגרסיבית יותר וכו'.
    • אם אתם מציגים תגובה חלופית על סמך הכותרת Save-Data, זכרו להוסיף אותה לרשימה Vary (Vary: Save-Data) כדי להורות למטמון ה-upstream שצריך לשמור במטמון ולהציג את הגרסה הזו רק אם כותרת הבקשה Save-Data קיימת. למידע נוסף, קראו את השיטות המומלצות לאינטראקציה עם מטמון.
  4. אם משתמשים בקובץ שירות (service worker), האפליקציה יכולה לזהות מתי האפשרות לשמירת נתונים מופעלת על ידי בדיקה אם קיימת כותרת הבקשה Save-Data, או על ידי בדיקת הערך של המאפיין navigator.connection.saveData. אם האפשרות הזו מופעלת, כדאי לבדוק אם אפשר לשכתב את הבקשה כדי לאחזר פחות בייטים, או להשתמש בתגובה שכבר אוחזרה.
  5. כדאי להגדיל את Save-Data באותות אחרים, כמו מידע על סוג החיבור של המשתמש והטכנולוגיה שלו (מידע נוסף זמין ב-NetInfo API). לדוגמה, יכול להיות שתרצו להציג את החוויה הקלה לכל משתמש בחיבור 2G, גם אם Save-Data לא מופעל. לחלופין, העובדה שהמשתמש נמצא בחיבור 4G 'מהיר' לא מעידה על כך שהוא לא מעוניין לשמור נתונים - למשל, בזמן נדידה. בנוסף, תוכלו לחזק את הנוכחות של Save-Data באמצעות רמז הלקוח Device-Memory כדי להתאים עוד יותר למשתמשים במכשירים עם זיכרון מוגבל. הזיכרון של מכשיר המשתמש מפורסם גם בהינט הלקוח של navigator.deviceMemory.

מתכונים

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

מתבצע חיפוש של Save-Data בקוד בצד השרת

המצב Save-Data הוא משהו שאפשר לזהות ב-JavaScript דרך המאפיין navigator.connection.saveData, אבל לפעמים עדיף לזהות אותו בצד השרת. במקרים מסוימים, JavaScript לא יכול לפעול. בנוסף, זיהוי בצד השרת הוא הדרך היחידה לשנות תגי עיצוב לפני שהם נשלחים ללקוח, ומעורבים בכמה מתרחישים לדוגמה השימושיים ביותר של Save-Data.

התחביר הספציפי לזיהוי הכותרת Save-Data בקוד בצד השרת תלוי בשפה שבה משתמשים, אבל הרעיון הבסיסי צריך להיות זהה בכל קצה עורפי של האפליקציה. לדוגמה, ב-PHP, כותרות הבקשות מאוחסנות במערך העל-גלובלי $_SERVER באינדקסים שמתחילים ב-HTTP_. פירוש הדבר הוא שאפשר לזהות את הכותרת Save-Data על ידי בדיקת הקיום והערך של המשתנה $_SERVER["HTTP_SAVE_DATA"], באופן הבא:

// false by default.
$saveData = false;

// Check if the `Save-Data` header exists and is set to a value of "on".
if (isset($_SERVER["HTTP_SAVE_DATA"]) && strtolower($_SERVER["HTTP_SAVE_DATA"]) === "on") {
  // `Save-Data` detected!
  $saveData = true;
}

אם מבצעים את הבדיקה הזו לפני ששולחים תגי עיצוב כלשהם ללקוח, המשתנה $saveData יכיל את המצב Save-Data ויהיה זמין לשימוש בכל מקום בדף. בעזרת הדגמה של המנגנון, נציג כאן כמה דוגמאות שממחישות איך אפשר להגביל את כמות הנתונים שנשלחת למשתמש.

הצגת תמונות ברזולוציה נמוכה במסכים עם רזולוציה גבוהה

תרחיש שימוש נפוץ לתמונות באינטרנט כרוך בהצגת תמונות בקבוצות של שניים: תמונה אחת למסכים "רגילים" (1x) ותמונה אחרת גדולה פי שניים (פי 2) למסכים עם רזולוציה גבוהה (למשל, תצוגת רטינה). סוג זה של מסכים ברזולוציה גבוהה לא בהכרח מוגבל למכשירים מתקדמים, והוא הופך להיות נפוץ יותר ויותר. במקרים שבהם עדיף להשתמש באפליקציה קלה יותר, מומלץ לשלוח למסכים האלה תמונות ברזולוציה נמוכה יותר (1x), ולא גרסאות גדולות יותר (2x). כדי לעשות זאת כשהכותרת Save-Data מופיעה, אנחנו פשוט משנים את תגי העיצוב שאנחנו שולחים ללקוח:

if ($saveData === true) {
  // Send a low-resolution version of the image for clients specifying `Save-Data`.
  ?><img src="butterfly-1x.jpg" alt="A butterfly perched on a flower."><?php
}
else {
  // Send the usual assets for everyone else.
  ?><img src="butterfly-1x.jpg" srcset="butterfly-2x.jpg 2x, butterfly-1x.jpg 1x" alt="A butterfly perched on a flower."><?php
}

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

אפשר גם להרחיב את הקונספט הזה למאפייני background-image ב-CSS על ידי הוספת מחלקה לרכיב <html>:

<html class="<?php if ($saveData === true): ?>save-data<?php endif; ?>">

מכאן תוכלו לטרגט את המחלקה save-data ברכיב <html> ב-CSS כדי לשנות את אופן העברת התמונות. ניתן לך לשלוח תמונות רקע ברזולוציה נמוכה למסכים ברזולוציה גבוהה כמו בדוגמה של ה-HTML שלמעלה, או להשמיט משאבים מסוימים לגמרי.

השמטת תמונות לא חיוניות

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

<p>This paragraph is essential content. The image below may be humorous, but it's not critical to the content.</p>
<?php
if ($saveData === false) {
  // Only send this image if `Save-Data` hasn't been detected.
  ?><img src="meme.jpg" alt="One does not simply consume data."><?php
}

לשיטה הזו בהחלט יכולה להיות אפקט בולט, כפי שאפשר לראות בדוגמה הבאה:

השוואה בין תמונות לא חיוניות שנטענות כשחסרים נתוני Save-Data, לבין אותן תמונות שמשמיטות כש-Save-Data זמין.
השוואה בין תמונות לא קריטיות שנטענות כשאין קובצי 'שמירת נתונים', לבין התמונות שהושמטו במקרה של מצב 'שמירת נתונים'.

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

השמטת גופני אינטרנט לא חיוניים

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

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

לדוגמה, נניח שכללת באתר שלך את Fira Sans מ-Google Fonts. Fira Sans הוא גופן מעולה להעתקת גוף, אבל אולי הוא לא חיוני למשתמשים שמנסים לשמור נתונים. על ידי הוספת מחלקה של save-data לרכיב <html> כשהכותרת Save-Data מופיעה, אנחנו יכולים לכתוב סגנונות שיפעילו בהתחלה את צורת הגופן הלא חיונית, אבל אחר כך אנחנו מפסיקים להשתמש בה כשהכותרת Save-Data קיימת:

/* Opt into web fonts by default. */
p,
li {
  font-family: 'Fira Sans', 'Arial', sans-serif;
}

/* Opt out of web fonts if the `save-Data` class is present. */
.save-data p,
.save-data li {
  font-family: 'Arial', sans-serif;
}

באמצעות גישה זו, ניתן להשאיר את קטע הקוד <link> מ-Google Fonts במקומו, כי הדפדפן טוען באופן ספקולטיבי משאבי CSS (כולל גופן אינטרנט) על ידי החלת סגנונות על ה-DOM ולאחר מכן בדיקה אם רכיבי HTML כלשהם מפעילים משאבים כלשהם בגיליון הסגנון. אם מישהו מפעיל את Save-Data, Fira Sans לא יטען אף פעם כי ה-DOM המעוצב אף פעם לא מפעיל אותו. במקום זאת, התהליך יישמע ב-&. זה לא טוב כמו Fira Sans, אבל יכול להיות שהוא עדיף למשתמשים שמנסים למתוח את תוכניות הנתונים שלהם.

סיכום

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

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

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

לפרטים נוספים על Save-Data ודוגמאות מעשיות מצוינת, ראו עזרה למשתמשים Save Data.