הסתגלות למשתמשים באמצעות רמזים ללקוחות

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

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

הכול עניין של משא ומתן על תוכן

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

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

Accept: image/webp,image/apng,image/*,*/*;q=0.8

כל הדפדפנים תומכים בפורמטים של תמונות כמו JPEG, PNG ו-GIF, אבל ב-Accept, במקרה הזה הדפדפן תומך גם ב-WebP וב-APNG. על סמך המידע הזה אנחנו יכולים לנהל משא ומתן על סוגי התמונות הטובים ביותר בכל דפדפן:

<?php
// Check Accept for an "image/webp" substring.
$webp = stristr($_SERVER["HTTP_ACCEPT"], "image/webp") !== false ? true : false;

// Set the image URL based on the browser's WebP support status.
$imageFile = $webp ? "whats-up.webp" : "whats-up.jpg";
?>
<img src="<?php echo($imageFile); ?>" alt="I'm an image!">

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

הבעת הסכמה

שלא כמו הכותרת Accept, רמזים ללקוחות לא מופיעים סתם בקסם (למעט Save-Data, שעליו נדון בהמשך). כדי שכותרות של בקשות יהיו מינימליות, אתם צריכים לבחור אילו רמזים ללקוחות תרצו לקבל. כדי לעשות זאת, שולחים את הכותרת Accept-CH כשמשתמש מבקש משאב:

Accept-CH: Viewport-Width, Downlink

הערך של Accept-CH הוא רשימה מופרדת בפסיקים של רמזים רצויים שהאתר ישתמש בהם כדי לקבוע את התוצאות לבקשות הבאות למשאבים. כשהלקוח קורא את הכותרת הזו, מופיעה ההודעה "האתר הזה מבקש את הרמזים של הלקוח Viewport-Width ו-Downlink". אל תדאגו לרמזים הספציפיים עצמם. נדבר על זה עוד רגע.

ניתן להגדיר את הכותרות האלה לשימוש בכל שפה של קצה עורפי. לדוגמה, ניתן להשתמש בפונקציה header של PHP. אפשר אפילו להגדיר את הכותרות האלה לבקשת הסכמה באמצעות המאפיין http-equiv בתג <meta>:

<meta http-equiv="Accept-CH" content="Viewport-Width, Downlink" />

כל הרמזים של הלקוח!

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

רמזים מהמכשיר

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

לפני שניכנס לרשימה הזו, כדאי ללמוד כמה מונחי מפתח לתיאור מסכים ורזולוציית מדיה:

גודל פנימי:הממדים בפועל של משאב מדיה. לדוגמה, אם פותחים תמונה ב-Photoshop, המימדים שמופיעים בתיבת הדו-שיח של גודל התמונה יתארו את הגודל הפנימי שלה.

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

<img
  src="whats-up-1x.png"
  srcset="whats-up-2x.png 2x, whats-up-1x.png 1x"
  alt="I'm that image you wanted."
/>

נניח שהגודל הפנימי של התמונה ב-1x הוא 320x240, והגודל הפנימי של התמונה 2x הוא 640x480. אם לקוח שמותקן במכשיר עם יחס פיקסלים של 2 למסך של תגי העיצוב האלה מנתחת את תגי העיצוב האלה (למשל, מסך רטינה), המערכת מבקשת את התמונה 2x. הגודל הפנימי המתוקן בדחיסות של התמונה של 2x הוא 320x240, כיוון שגודל 640x480 חלקי 2 הוא 320x240.

גודל חיצוני: הגודל של משאב מדיה אחרי שהוחלו עליו CSS וגורמי פריסה אחרים (כמו width ו-height). נניח שיש לכם רכיב <img> שטוען תמונה בגודל פנימי 320x240 שתוקן בצפיפות, אבל יש לו גם מאפייני CSS width ו-height שחלים עליו הערכים 256px ו-192px, בהתאמה. בדוגמה הזו, הגודל החיצוני של אותו רכיב <img> הופך ל-256x192.

איור של גודל פנימי לעומת
גודל קיצוני. תיבה בגודל 320x240 פיקסלים מוצגת עם תווית &#39;גודל פנימי&#39;. בתוכה יש תיבה קטנה יותר בגודל 256x192 פיקסלים, שמייצגת רכיב HTML img עם CSS שהוחל עליו. התיבה הזו מסומנת בתווית EXTRINSIC SIZE. בצד שמאל מופיעה תיבה שמכילה CSS שהופעלה על הרכיב, שמשנה את הפריסה של רכיב ה-img כך שהגודל החיצוני שלו שונה מהגודל הפנימי שלו.
איור 1. איור של גודל פנימי לעומת גודל קיצוני. התמונה הופכת לגודל החיצוני שלה אחרי שהוחלו עליה גורמי הפריסה. במקרה הזה, החלה של כללי CSS של width: 256px; ו-height: 192px; משנה תמונה בגודל פנימי של 320x240 לתמונה בגודל 256x192.

בואו נסתכל על רשימת הרמזים הספציפיים של מכשיר שהם זמינים לכם.

רוחב אזור התצוגה

Viewport-Width הוא הרוחב של אזור התצוגה של המשתמש בפיקסלים של CSS:

Viewport-Width: 320

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

DPR

DPR, קיצור של יחס הפיקסלים של המכשיר, מדווח על היחס בין פיקסלים פיזיים לפיקסלים של CSS במסך של המשתמש:

DPR: 2

הרמז הזה שימושי כשבוחרים מקורות של תמונות שמתאימים לדחיסות הפיקסלים של המסך (כמו שמתוארים בx במאפיין srcset).

רוחב

ההינט Width מופיע בבקשות למשאבי תמונות שהופעלו על ידי תגי <img> או <source> באמצעות המאפיין sizes. sizes מורה לדפדפן מה יהיה הגודל החיצוני של המשאב. Width משתמש בגודל החיצוני הזה כדי לבקש תמונה בגודל פנימי שמתאים לפריסה הנוכחית.

לדוגמה, נניח שמשתמש מבקש דף עם מסך רחב של פיקסל 320 CSS עם DPR של 2. המכשיר טוען מסמך עם רכיב <img> שמכיל ערך מאפיין sizes של 85vw (כלומר 85% מרוחב אזור התצוגה בכל גודלי המסכים). אם אישרתם את הרמז Width, הלקוח ישלח לשרת את הרמז Width הזה עם הבקשה ל-src של <img>:

Width: 544

במקרה הזה, הלקוח רומז לשרת שהרוחב הפנימי האופטימלי של התמונה המבוקשת יהיה 85% מרוחב אזור התצוגה (272 פיקסלים) כפול ה-DPR של המסך (2), שווה 544 פיקסלים.

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

תוכן – DPR

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

בשונה מרמזים אחרים של לקוח, Content-DPR היא לא כותרת בקשה לשימוש של שרתים, אלא שרתי כותרות של תגובה חייבים לשלוח בכל פעם שנעשה שימוש ברמזים DPR ו-Width כדי לבחור משאב. הערך של Content-DPR צריך להיות התוצאה של המשוואה הבאה:

Content-DPR = [גודל מקור התמונה שנבחר] / ([Width] / [DPR])

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

זיכרון המכשיר

מבחינה טכנית, Device-Memory הוא חלק מ-Device Memory API, והוא חושף את כמות הזיכרון המשוערת שיש במכשיר הנוכחי ב-GiB:

Device-Memory: 2

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

רמזים לגבי הרשת

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

RTT

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

RTT: 125

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

אמנם זמן האחזור הוא חשוב בביצועי הטעינה, אבל רוחב הפס משפיע גם כן. הרמז Downlink, שמוצג במגה-ביט לשנייה (Mbps), חושף את המהירות הצפויה במורד הזרם של החיבור של המשתמש:

Downlink: 2.5

בשילוב עם RTT, אפשר להיעזר ב-Downlink כדי לשנות את האופן שבו התוכן נשלח למשתמשים בהתאם לאיכות החיבור לרשת.

שעון אקוודור

הינט ECT מייצג את Effective Connection Type. הערך שלו הוא אחד מתוך רשימה ממוספרת של סוגי חיבורים, שכל אחד מהם מתאר חיבור בטווחים שצוינו של הערכים RTT ו-Downlink.

הכותרת לא מסבירה מה סוג החיבור בפועל – לדוגמה, לא מצוין בה אם השער הוא מגדל תקשורת או נקודת גישה ל-Wi-Fi. במקום זאת, היא מנתחת את זמן האחזור ואת רוחב הפס של החיבור הנוכחי וקובע לאיזה פרופיל רשת הכי דומה לו. לדוגמה, אם תתחברו דרך Wi-Fi לרשת איטית, ייתכן שיופיע הערך ECT בערך 2g, שהוא אומדן הקרוב ביותר לחיבור האפקטיבי:

ECT: 2g

הערכים החוקיים של ECT הם 4g, 3g, 2g ו-slow-2g. אפשר להשתמש ברמז הזה כנקודת התחלה להערכת איכות החיבור, ולאחר מכן לחדד אותו באמצעות הרמזים RTT ו-Downlink.

שמירת נתונים

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

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

Save-Data: on

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

קישור של כל המידע

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

תמונות רספונסיביות

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

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

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

  1. אם זה רלוונטי לתהליך העבודה שלכם, קודם כל צריך לבחור טיפול בתמונה (כלומר תמונות מוכוונות אומנות) על ידי בדיקת הרמז Viewport-Width.
  2. כדי לבחור רזולוציית תמונה בודקים את הרמז Width ואת הרמז DPR ובוחרים מקור שמתאים לגודל פריסת התמונה ולדחיסות המסך (בדומה לאופן שבו פועלים התיאורים x ו-w ב-srcset).
  3. צריך לבחור את פורמט הקובץ האופטימלי שבו הדפדפן תומך (ברוב הדפדפנים יש משהו ש-Accept יכול לעשות).

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

<picture>
  <source
    srcset="
      company-photo-256w.webp   256w,
      company-photo-512w.webp   512w,
      company-photo-768w.webp   768w,
      company-photo-1024w.webp 1024w,
      company-photo-1280w.webp 1280w
    "
    type="image/webp"
  />
  <img
    srcset="
      company-photo-256w.jpg   256w,
      company-photo-512w.jpg   512w,
      company-photo-768w.jpg   768w,
      company-photo-1024w.jpg 1024w,
      company-photo-1280w.jpg 1280w
    "
    src="company-photo-256w.jpg"
    sizes="(min-width: 560px) 251px, 88.43vw"
    alt="The Sconnie Timber Staff!"
  />
</picture>

בהתאם לתמיכה בדפדפן, הצלחתי לצמצם אותה למספר הבא:

<img
  src="/image/sizes:true/company-photo.jpg"
  sizes="(min-width: 560px) 251px, 88.43vw"
  alt="SAY CHEESY PICKLES."
/>

בדוגמה הזו, כתובת ה-URL של /image היא סקריפט ב-PHP ואחריו פרמטרים שנכתבים על ידי mod_rewrite. הוא דורש שם קובץ של תמונה ופרמטרים נוספים כדי לעזור לסקריפט עורפי לבחור את התמונה הטובה ביותר בתנאים הנתונים.

אני מבין ש"אבל לא פשוט מטמיעים מחדש את <picture> ואת srcset?" זאת השאלה הראשונה שלך.

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

רמזים ללקוחות מאפשרים להתחיל עם תמונה ברזולוציה גבוהה וברזולוציה גבוהה, שאפשר לשנות את הגודל שלה באופן דינמי כדי להיות אופטימליים לכל שילוב של מסך ופריסה. בניגוד ל-srcset, שדורש ספירה של רשימה קבועה של תמונות אפשריות לבחירה מהדפדפן, הגישה הזו יכולה להיות גמישה יותר. בעוד ש-srcset מאלץ אתכם להציע לדפדפנים קבוצה גסה של וריאנטים – למשל, 256w, 512w, 768w ו-1024w – פתרון מבוסס-רמזים ללקוח יכול להציג מודעות בכל הרוחב, בלי ערימה ענקית של תגי עיצוב.

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

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

עזרה למשתמשים ברשתות איטיות

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

בכל הנוגע לאתר של Sconni Timber, אנחנו נוקטים פעולות כדי להקל על העומס כשהרשתות איטיות, והכותרות Save-Data, ECT, RTT ו-Downlink נבדקות בקוד העורפי שלנו. לאחר מכן, אנחנו יוצרים ציון איכות ברשת, שלפיו אנחנו יכולים לקבוע אם עלינו להתערב כדי לשפר את חוויית המשתמש. ציון הרשת הזה הוא בין 0 ל-1, ושם 0 היא איכות הרשת הנמוכה ביותר האפשרית ו-1 היא האיכות הטובה ביותר.

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

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

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

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

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

מפל WebPagetest באתר Sconlie
שטוען את כל המשאבים בחיבור רשת איטי.
איור 3. אתר עם הרבה עומסים שטוען תמונות, סקריפטים וגופנים בחיבור איטי.

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

מפל WebPagetest של אתר Sconlie Timber שמשתמש ברמזים ללקוח כדי להחליט לא לטעון משאבים לא קריטיים בחיבור איטי לרשת.
איור 4. באותו אתר עם אותו חיבור, רק המשאבים מסוג 'נחמד שיש' מוחרגים לטובת טעינה מהירה יותר.

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

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

// Set the ECT value to "4g" by default.
$ect = isset($_SERVER["HTTP_ECT"]) ? $_SERVER["HTTP_ECT"] : "4g";

בדוגמה הזו, "4g" מייצג את החיבור לרשת באיכות הגבוהה ביותר שמתוארת בכותרת ECT. אם נפעיל את $ect ל-"4g", לא תהיה לכך השפעה על דפדפנים שלא תומכים ברמזים ללקוחות. הצטרף ל-FTW!

חשוב לזכור את המטמון!

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

Vary: DPR, Width

עם זאת, יש אזהרה גדולה: אף פעם לא כדאי Vary תגובות שניתנות לשמירה במטמון בכותרת שמשתנה לעיתים קרובות (כמו Cookie), כי המשאבים האלה למעשה לא ניתנים לשמירה במטמון. על סמך המידע הזה, כדאי להימנע מ-Vary בכותרות של רמזים ללקוח, כמו RTT או Downlink, כי אלו גורמי חיבור שעשויים להשתנות לעיתים קרובות. אם רוצים לשנות את התגובות בכותרות האלה, כדאי להוסיף רק את הכותרת ECT, כדי לצמצם למינימום שגיאות במטמון.

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

רמזים של לקוחות ב-Service Workers

משא ומתן על תוכן כבר לא מיועד רק לשרתים! מכיוון ש-Service Workers פועלים כשרתי proxy בין הלקוחות לשרתים, יש לכם שליטה על אופן העברת המשאבים באמצעות JavaScript. המידע הזה כולל רמזים ללקוח. באירוע של קובץ השירות (service worker) fetch, אפשר להשתמש ב-method request.headers.get של האובייקט event כדי לקרוא את כותרות הבקשות של המשאב באופן הבא:

self.addEventListener('fetch', (event) => {
  let dpr = event.request.headers.get('DPR');
  let viewportWidth = event.request.headers.get('Viewport-Width');
  let width = event.request.headers.get('Width');

  event.respondWith(
    (async function () {
      // Do what you will with these hints!
    })(),
  );
});

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

רמז ללקוח מקבילה ב-JS
'ECT' `navigator.connection.effectiveType`
'RTT' 'navigator.connect.rtt'
'שמירת נתונים' `navigator.connection.saveData`
'קישור למטה' `navigator.connection.downlink`
'זיכרון מכשיר' 'navigator.deviceMemory'
יישומי פלאגין של Imagemin לסוגי קבצים.

ממשקי ה-API האלה לא זמינים בכל מקום שבו צריך לבדוק את התכונות באמצעות האופרטור in:

if ('connection' in navigator) {
  // Work with netinfo API properties in JavaScript!
}

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

סיכום

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

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

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

משאבים

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