התאמת אתר ה-HTML5 שלך

אריק בידלמן

מבוא

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

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

יצירת html5rocks.com שמתאים לניידים

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

במאמר הזה אנחנו בוחנים איך יצרנו גרסה לנייד של html5rocks עם אופטימיזציה למכשירי Android ו-iOS. פשוט טען את html5rocks.com במכשיר שתומך באחת ממערכות ההפעלה האלה כדי לראות את ההבדל. אין הפניות אוטומטיות אל m.html5rocks.com או לטיפה כלכלית אחרת מהסוג הזה. מקבלים html5rocks כמו שהוא... עם היתרון הנוסף של משהו שנראה נהדר ועובד היטב במכשיר נייד.

מחשב html5rocks.com html5rocks.com לנייד
html5rocks.com במחשב (ימין) ובנייד (בצד ימין)

שאילתות מדיה של CSS

HTML4 ו-CSS2 תומכים בגיליונות סגנונות תלויי מדיה כבר זמן מה. לדוגמה:

<link rel="stylesheet" media="print" href="printer.css">

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

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

טירגוט לגדלים של מסכים

בדוגמה הבאה, phone.css יחול על מכשירים שהדפדפן מתייחס אליהם כ"ניידים" או על מכשירים עם מסכים ברוחב של פחות מ-320px.

 <link rel='stylesheet'
  media='handheld, only screen and (max-device-width: 320px)' href='phone.css'>

הוספת לפני שאילתות מדיה למילת המפתח "only" תגרום לכך שדפדפנים שלא תואמים ל-CSS3 יתעלמו מהכלל.

הדגמים הבאים יטרגטו למסכים של 641px עד 800px:

 <link rel='stylesheet'
  media='only screen and (min-width: 641px) and (max-width: 800px)' href='ipad.css'>

שאילתות מדיה יכולות להופיע גם בתוך תגי <style> מוטבעים. הפריטים הבאים מטרגטים all סוגי מדיה כשהם מוצגים לאורך:

 <style>
  @media only all and (orientation: portrait) { ... }
 </style>

media="handheld"

אנחנו צריכים לעצור לדקה ולדון על media="handheld". עובדה היא, מערכות Android ו-iOS מתעלמות מ-media="handheld". הטענה היא שהמשתמשים יחמיצו את התוכן היוקרתי שמסופק על ידי גיליונות סגנונות שמטרגטים את media="screen", והסיכוי שהמפתחים ישמרו על גרסה media="handheld" באיכות נמוכה יותר עשוי להיות נמוך יותר. לכן, כחלק מהעקרונות של "האינטרנט המלא", רוב הדפדפנים המודרניים לסמארטפונים פשוט מתעלמים מגיליונות סגנונות ידניים.

מומלץ להשתמש בתכונה הזו כדי לטרגט מכשירים ניידים, אבל דפדפנים שונים יישמו אותה בדרכים שונות:

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

Opera Mini לא מתעלמת מ-media="handheld". כדי לגרום ל-Windows Mobile לזהות את media="handheld", צריך להשתמש באותיות רישיות בערך מאפיין המדיה עבור גיליון הסגנונות של המסך:

 <!-- media="handheld" trick for Windows Mobile -->
 <link rel="stylesheet" href="screen.css" media="Screen">
 <link rel="stylesheet" href="mobile.css" media="handheld">

איך html5rocks משתמש בשאילתות מדיה

שאילתות מדיה נמצאות בשימוש נרחב ב-html5rocks בנייד. הם אפשרו לנו לשנות את הפריסה בלי לבצע שינויים משמעותיים בתגי העיצוב של תבנית Django... ממש הצלה! בנוסף, התמיכה שלהם בדפדפנים השונים די טובה.

ב-<head> של כל דף יופיעו גיליונות הסגנונות הבאים:

 <link rel='stylesheet'
  media='all' href='/static/css/base.min.css' />
 <link rel='stylesheet'
  media='only screen and (max-width: 800px)' href='/static/css/mobile.min.css' />

base.css הגדירה תמיד את המראה והתחושה המרכזיים של html5rocks.com, אבל עכשיו אנחנו מיישמים סגנונות חדשים (mobile.css) למסכים ברוחב של פחות מ-800px. שאילתת המדיה של המודעה מתייחסת לטלפונים חכמים (כ-320 פיקסלים) ול-iPad (כ-768 פיקסלים). התוצאה: אנחנו מחליפים סגנונות ב-base.css בהדרגה (רק לפי הצורך) כדי לשפר את מראה האתר.

חלק משינויי הסגנון ש-mobile.css אוכף:

  • הפחתת רווחים/מרווח פנימי מיותרים באתר. במסכים קטנים, השטח הוא כל כך יקר!
  • הסרה של :hover מצבים. הם אף פעם לא נראים במכשירי מגע.
  • מתאים את הפריסה לעמודה אחת. נרחיב בנושא הזה בהמשך.
  • מסיר את box-shadow שמסביב למאגר הראשי div של האתר. צלליות תיבה גדולות מפחיתות את ביצועי הדף.
  • נעשה שימוש במודל תיבה גמישה של CSS box-ordinal-group כדי לשנות את הסדר של כל קטע בדף הבית. הכיתוב 'לימודים לפי קבוצות תכונות ראשיות של HTML5' מופיע לפני הקטע 'מדריכים' בדף הבית, אבל אחריו מופיע בגרסה לנייד. הסדר הזה הגיוני יותר לניידים ולא דרש שינויים בתגי עיצוב. CSS flexbox FTW!
  • opacity שינויים יוסרו. שינוי ערכי אלפא הוא להיט בניידים.

מטא תגים לנייד

Mobile WebKit תומך בכמה דברים טובים שמעניקים למשתמשים חוויית גלישה טובה יותר במכשירים מסוימים.

הגדרות אזור התצוגה

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

 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">

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

 <meta name=viewport
  content="width=device-width, initial-scale=1.0, minimum-scale=0.5 maximum-scale=1.0">

Android מרחיב את המטא תג של אזור התצוגה ומאפשר למפתחים לציין לאיזו רזולוציית מסך האתר פותח:

 <meta name="viewport" content="target-densitydpi=device-dpi">

הערכים האפשריים של target-densitydpi הם device-dpi, high-dpi, medium-dpi, low-dpi.

אם תרצו לשנות את דף האינטרנט כך שיתאים לצפיפויות מסך שונות, צריך להשתמש בשאילתת המדיה -webkit-device-pixel-ratio ב-CSS ו/או במאפיין window.devicePixelRatio ב-JavaScript, ואז להגדיר את המטא נכס target-densitydpi כ-device-dpi. כך מערכת Android לא מבצעת סילומיות אנכית (scale up) בדף האינטרנט, ומאפשרת לכם לבצע את ההתאמות הנדרשות לכל דחיסות באמצעות CSS ו-JavaScript.

למידע נוסף על טירגוט רזולוציות של מכשירים, עיינו במסמכי התיעוד בנושא WebView של Android.

גלישה במסך מלא

יש שני ערכי מטא נוספים שתואמים ל-iOS. apple-mobile-web-app-capable ו-apple-mobile-web-app-status-bar-style יבצעו עיבוד של תוכן הדף במצב של מסך מלא דמוי-אפליקציה, כך ששורת הסטטוס תהיה שקופה:

 <meta name="apple-mobile-web-app-capable" content="yes">
 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

למידע נוסף על כל אפשרויות המטא הזמינות, עיינו במסמכי התיעוד של Safari.

סמלים של מסך הבית

מכשירי iOS ו-Android מקבלים גם rel="apple-touch-icon" (iOS) ו-rel="apple-touch-icon-precomposed" (Android) לקישורים. הפרמטרים האלה יוצרים סמל מהבהב דמוי אפליקציה במסך הבית של המשתמשים כשהם מוסיפים את האתר שלכם לסימניות:

 <link rel="apple-touch-icon"
      href="/static/images/identity/HTML5_Badge_64.png" />
 <link rel="apple-touch-icon-precomposed"
      href="/static/images/identity/HTML5_Badge_64.png" />

איך html5rocks משתמש במטא תגים לנייד

אם נסכם את כל המרכיבים, הנה קטע טקסט מהקטע <head> ב-html5rocks:

 <head>
  ...
   <meta name="viewport"
        content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />

   <link rel="apple-touch-icon"
        href="/static/images/identity/HTML5_Badge_64.png" />
   <link rel="apple-touch-icon-precomposed"
        href="/static/images/identity/HTML5_Badge_64.png" />
  ...
 </head>

פריסה אנכית

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

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

אופטימיזציה לנייד

רוב האופטימיזציות שביצענו הן דברים שהיו צריכים לבצע מלכתחילה. דברים כמו צמצום מספר הבקשות ברשת, דחיסת JS/CSS , gzipping (מגיע בחינם ב-App Engine) וצמצום מניפולציות ב-DOM. השיטות האלה הן שיטות מומלצות נפוצות, אבל מדי פעם שוכחים אותן כשמנסים להגיע לאתר.

הסתרה אוטומטית של סרגל הכתובות

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

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

סרגל הכתובות.
סרגל הכתובות המכוער תופס שטח במסך.
  // Hides mobile browser's address bar when page is done loading.
  window.addEventListener('load', function(e) {
    setTimeout(function() { window.scrollTo(0, 1); }, 1);
  }, false);

בנוסף, תיקנו את ה-listener הזה הוא משתנה התבנית is_mobile כי לא צריך אותו במחשב.

הפחתת בקשות רשת, חיסכון ברוחב פס

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

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

  • הסרת מסגרות iframe – מסגרות iframe איטיות! חלק גדול מזמן האחזור שלנו הגיע מווידג'טים של שיתוף של צד שלישי (באז, Google Friends Connect, Twitter, Facebook) בדפי ההדרכה. ממשקי ה-API האלה נכללו באמצעות תגי <script>, והם יוצרים מסגרות iframe שמפחיתות את מהירות הדף. הווידג'טים הוסרו לנייד.

  • display:none – במקרים מסוימים, הסתרתנו תגי עיצוב אם הם לא התאימו לפרופיל הנייד. דוגמה טובה הייתה ארבע התיבות המעוגלות בחלק העליון של דף הבית:

לחצני תיבה בדף הבית.
לחצני תיבה בדף הבית.

הן לא מופיעות באתר לנייד. חשוב לזכור שהדפדפן עדיין שולח בקשה לכל סמל, למרות שהמאגר שלו מוסתר באמצעות display:none. לכן לא מספיק פשוט להסתיר את הלחצנים האלה. זה לא רק בזבוז רוחב פס, אלא שגם המשתמש לא יוכל לראות את הפירות של רוחב הפס המבוזבז הזה! הפתרון היה ליצור ערך בוליאני "is_mobile" בתבנית Django כדי להשמיט קטעי HTML באופן מותנה. כשהמשתמש צופה באתר במכשיר חכם, הלחצנים לא מוצגים.

  • מטמון האפליקציה - לא רק שהתמיכה הזו נותנת לנו תמיכה אופליין, אלא גם יוצרת הפעלה מהירה יותר.

  • דחיסת CSS/JS – אנחנו משתמשים בדחיסת YUI במקום במהדר סגירה, בעיקר מפני שהוא מטפל גם ב-CSS וגם ב-JS. אחת הבעיות שבהן נתקלנו הייתה שאילתות מדיה מוטבעות (שאילתות מדיה שמופיעות בתוך גיליון סגנונות) שנוספו במדחס YUI 2.4.2 (ראו בעיה זו). שימוש ב-YUI Compressor 2.4.4+ פתר את הבעיה.

  • שימוש ב-Sprits של תמונות CSS כאשר זה אפשרי.

  • נעשה שימוש ב-pngcrush לדחיסת תמונה.

  • נעשה שימוש במזהי URI של תמונות קטנות. קידוד Base64 מוסיף לתמונה כ-30%או יותר מהגודל, אבל בקשת הרשת נשמרת.

  • בוצעה טעינה אוטומטית של 'חיפוש מותאם אישית של Google' באמצעות תג סקריפט יחיד במקום לטעון אותו באופן דינמי באמצעות google.load(). השניה מוגשת בקשה נוספת.

<script src="//www.google.com/jsapi?autoload={"modules":[{"name":"search","version":"1"}]}"> </script>
  • מדפסת הקוד היפה והמודרניזר נכללו בכל דף, גם אם מעולם לא נעשה בהן שימוש. Modernizr הוא מעולה, אבל הוא מריץ כמה בדיקות בכל טעינה. חלק מהבדיקות האלה מבצעות שינויים יקרים ב-DOM ומאטות את טעינת הדף. עכשיו אנחנו כוללים את הספריות האלה רק בדפים שבהם הן נחוצות בפועל. -2 בקשות :)

שינויים נוספים בביצועים:

  • העברת את כל ה-JS לחלק התחתון של הדף (במידת האפשר).
  • הוסרו תגי <style> מוטבעים.
  • חיפושי DOM במטמון ומניפולציות מינימליות ב-DOM – בכל פעם שנוגעים ב-DOM, הדפדפן מבצע הזרמה מחדש. הזרימות חוזרות עולות אפילו יותר במכשירים ניידים.
  • הוצא קוד מבוזבז בצד הלקוח מהשרת. באופן ספציפי, הבדיקה מאפשרת להגדיר את סגנון הניווט בדף הנוכחי: js var lis = document.querySelectorAll('header nav li'); var i = lis.length; while (i--) { var a = lis[i].querySelector('a'); var section = a.getAttribute("data-section"); if (new RegExp(section).test(document.location.href)) { a.className = 'current'; } }
  • אלמנטים עם רוחב קבוע הוחלפו בנוזל width:100% או width:auto.

מטמון של אפליקציה

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

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

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

- url: /(.*\.(appcache|manifest))
  static_files: \1
  mime_type: text/cache-manifest
  upload: (.*\.(appcache|manifest))
  expiration: "0s"

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

window.applicationCache.addEventListener('updateready', function(e) {
  if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
    window.applicationCache.swapCache();
    if (confirm('A new version of this site is available. Load it?')) {
      window.location.reload();
    }
  }
}, false);

כדי לחסוך את התנועה ברשת, צריך להשתמש במניפסט פשוט. כלומר, אל תקראו לכל דף באתר שלכם. פשוט פרטו את התמונות החשובות, קובצי CSS וקובצי JavaScript. הדבר האחרון שצריך לעשות הוא לאלץ את הדפדפן לנייד להוריד מספר גדול של נכסים בכל עדכון appcache. במקום זאת, חשוב לזכור שהדפדפן שומר דף HTML באופן לא מפורש כשהמשתמש מבקר בו (והוא כולל את המאפיין <html manifest="...">).