מבוא
פיתוח לאינטרנט לנייד הוא נושא חם בימים אלה. השנה, בפעם הראשונה בהיסטוריה, מכירות הסמארטפונים עלו על מכירות המחשבים האישיים. יותר ויותר משתמשים משתמשים במכשיר נייד כדי לגלוש באינטרנט, ולכן חשוב מאוד שמפתחים יבצעו אופטימיזציה לאתרים שלהם לדפדפנים לנייד.
שדה הקרב 'נייד' עדיין לא מוכר למספר גדול של מפתחים. לאנשים רבים יש אתרים ישנים שלא מתאימים בכלל למשתמשים בנייד. במקום זאת, האתר תוכנן בעיקר לגלישה במחשב, והוא לא מותאם בצורה טובה לדפדפנים בנייד. האתר הזה (html5rocks.com) הוא לא יוצא דופן. בזמן ההשקה, הקדשנו מעט מאמץ לגרסת האתר לנייד.
יצירת אתר html5rocks.com שמותאם לניידים
כתרגיל, חשבתי שיהיה מעניין להשתמש באתר html5rocks (אתר HTML5 קיים) ולהוסיף לו גרסה שמתאימה לניידים. הדבר העיקרי שעניין אותי היה כמות העבודה המינימלית שנדרשת כדי לטרגט לטלפונים חכמים. המטרה של התרגיל שלי לא הייתה ליצור אתר חדש לגמרי לנייד ולנהל שתי גרסאות של קוד. זה היה לוקח לנצח והיה בזבוז זמן עצום. כבר הגדרנו את המבנה של האתר (תגי עיצוב). בדקנו את המראה והתחושה (CSS). הפונקציונליות העיקרית (JS) הייתה שם. העניין הוא שהרבה אתרים נמצאים באותה סירה.
במאמר הזה נסביר איך יצרנו גרסה לנייד של html5rocks שמותאמת למכשירי Android ו-iOS. כדי לראות את ההבדל, פשוט טוענים את html5rocks.com במכשיר שתומך באחת ממערכת ההפעלה האלה. אין הפניות אוטומטיות לכתובת m.html5rocks.com או תרמיות אחרות מהסוג הזה. אתם מקבלים את html5rocks כמו שהוא… עם היתרון הנוסף של משהו שנראה נהדר ופועל היטב במכשיר נייד.


שאילתות מדיה של CSS
כבר זמן מה יש תמיכה ב-HTML4 וב-CSS2 בגיליונות סגנונות שמותאמים למדיה. לדוגמה:
<link rel="stylesheet" media="print" href="printer.css">
יטרגטו למכשירי הדפסה ויספקו עיצוב ספציפי לתוכן הדף כשהוא מודפס. ב-CSS3, הרעיון של סוגי מדיה מקבל ביטוי נוסף, והפונקציונליות שלהם משופרת באמצעות שאילתות מדיה. שאילתות מדיה מרחיבות את התועלת של סוגי המדיה על ידי מתן אפשרות לתיוג מדויק יותר של גיליונות סגנונות. כך אפשר להתאים אישית את הצגת התוכן למגוון ספציפי של מכשירי פלט, בלי לשנות את התוכן עצמו. זה נשמע מושלם לפריסת אתר קיימת שצריך לשנות.
אפשר להשתמש בשאילתות מדיה במאפיין media
של גיליונות הסגנון החיצוניים כדי לטרגט את רוחב המסך, רוחב המכשיר, הכיוון וכו'. הרשימה המלאה מופיעה במפרט של שאילתות המדיה של W3C.
טירגוט לפי גדלי מסכים
בדוגמה הבאה, phone.css
יחול על מכשירים שהדפדפן מחשיב כ'ניידים' או על מכשירים עם מסכים ברוחב של 320 פיקסלים לכל היותר.
<link rel='stylesheet'
media='handheld, only screen and (max-device-width: 320px)' href='phone.css'>
הוספת מילת המפתח only
כתחילית לשאילתות מדיה תגרום לדפדפנים שלא תואמים ל-CSS3 להתעלם מהכלל.
הקריטריונים הבאים יטרגטו מסכים בגדלים שבין 641 פיקסלים ל-800 פיקסלים:
<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 הראשי של מאגר האתר. צללי תיבות גדולים פוגעים בביצועי הדף. - השתמשו במודל
box-ordinal-group
של תיבות גמישות ב-CSS כדי לשנות את הסדר של כל קטע בדף הבית. תוכלו לראות שהקטע 'לימוד לפי קבוצות עיקריות של תכונות HTML5' מופיע לפני הקטע 'מדריכים' בדף הבית, אבל אחריו בגרסה לנייד. הסדר הזה הגיוני יותר בנייד ולא נדרש בו שינוי ברכיבי ה-Markup. 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
.
אם רוצים לשנות את דף האינטרנט בהתאם לצפיפות המסך, משתמשים בשאילתת המדיה מסוג CSS -webkit-device-pixel-ratio
ו/או במאפיין window.devicePixelRatio
ב-JavaScript, ולאחר מכן מגדירים את מאפיין המטא target-densitydpi
לערך device-dpi
. כך מערכת Android לא תשנה את הגודל של דף האינטרנט, ותוכלו לבצע את השינויים הנדרשים לכל צפיפות באמצעות CSS ו-JavaScript.
מידע נוסף על טירגוט לפי רזולוציות של מכשירים זמין במסמכי התיעוד של Android בנושא WebView.
גלישה במסך מלא
יש עוד שני ערכי מטא שהם iOS-sfic. 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 כדי ליצור פריסה כזו. שוב, בלי לשנות את ה-Markup.




אופטימיזציה לנייד
רוב האופטימיזציות שביצענו הן פעולות שצריך היה לבצע מלכתחילה. למשל, צמצום מספר הבקשות לרשת, דחיסת JS/CSS, דחיסת gzip (התכונה הזו זמינה בחינם ב-App Engine) ומזעור של מניפולציות על DOM. הטכניקות האלה הן שיטות מומלצות נפוצות, אבל לפעמים הן לא נלקחות בחשבון כשרוצים להפעיל אתר במהירות.
הסתרה אוטומטית של סרגל הכתובות
בדפדפנים לנייד אין את שטח המסך שיש בדפדפנים למחשב. גרוע מכך, בפלטפורמות שונות לפעמים מופיעה סרגל כתובות גדול בחלק העליון של המסך… גם אחרי שהדף מסיים להיטען.
דרך קלה אחת להתמודד עם הבעיה היא לגלול בדף באמצעות JavaScript.
גם אם תזוזו רק פיקסל אחד, סרגל הכתובות הטורדני ייעלם.
כדי להסתיר בכוח את סרגל הכתובות ב-html5rocks, צרפתי לטפל באירועים מסוג 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);
בנוסף, עטפנו את המאזין הזה במשתנה התבנית is_mobile
, כי אין צורך בו במחשב.
צמצום מספר הבקשות לרשת, חיסכון ברוחב הפס
ידוע שצמצום מספר בקשות ה-HTTP יכול לשפר את הביצועים באופן משמעותי. במכשירים ניידים יש הגבלה נוספת על מספר החיבורים בו-זמנית שהדפדפן יכול ליצור, ולכן אתרים לנייד ירוויחו עוד יותר מהפחתת הבקשות הלא רלוונטיות האלה. בנוסף, חשוב לחסוך בכל בייט כי לרוב רוחב הפס מוגבל בטלפונים. יכול להיות שאתם גורמים למשתמשים להוציא כסף!
ריכזנו כאן כמה מהגישות שלנו לצמצום הבקשות לרשת ולהפחתת רוחב הפס ב-html5rocks:
הסרת iframes – iframes איטיים! חלק גדול מהזמן שחלף מהקליק להצגת הדף נובע מווידג'טים של צד שלישי לשיתוף (Buzz, Google Friend Connect, Twitter, Facebook) בדפי ההדרכה. ממשקי ה-API האלה נכללו באמצעות תגי
<script>
ויוצרים iframes שמפחיתים את מהירות הדף. הווידג'טים הוסרו מהנייד.display:none
– במקרים מסוימים, הוסתרנו את ה-Markup אם הוא לא התאים לפרופיל לנייד. דוגמה טובה לכך היא ארבעת התיבות העגולות בחלק העליון של דף הבית:

הם חסרים באתר לנייד. חשוב לזכור שהדפדפן עדיין שולח בקשה לכל סמל, למרות שהמאגר שלהם מוסתר באמצעות display:none
. לכן, לא מספיק פשוט להסתיר את הלחצנים האלה. לא רק שזה יהיה בזבוז של רוחב פס, אלא שהמשתמש לא ייהנה מהרוחב הפס הזה. הפתרון היה ליצור משתנה בוליאני בשם 'is_mobile' בתבנית Django כדי להשמיט קטעי HTML באופן מותנה.
כשהמשתמשים צופים באתר במכשיר חכם, הלחצנים לא מוצגים.
מטמון אפליקציה – הוא לא רק מספק לנו תמיכה במצב אופליין, אלא גם מאפשר הפעלה מהירה יותר.
דחיסת CSS/JS – אנחנו משתמשים ב-YUI compressor במקום ב-Closure compiler, בעיקר כי הוא מטפל גם ב-CSS וגם ב-JS. אחת הבעיות שבהן נתקלנו היא ששאילתות מדיה בקוד (שאילתות מדיה שמופיעות בתוך גיליון סגנונות) גרמו לבעיה ב-YUI compressor 2.4.2 (ראו הבעיה הזו). הבעיה נפתרה באמצעות YUI Compressor מגרסה 2.4.4 ואילך.
שימוש ב-CSS sprites של תמונות כשהדבר אפשרי.
נעשה שימוש ב-pngcrush לדחיסת תמונות.
שימוש ב-dataURIs לתמונות קטנות. קידוד Base64 מוסיף לתמונה כ-30%יותר גודל, אבל חוסך את בקשת הרשת.
חיפוש Google בהתאמה אישית נטען באופן אוטומטי באמצעות תג סקריפט יחיד, במקום לטעון אותו באופן דינמי באמצעות
google.load()
. האפשרות השנייה שולחת בקשה נוספת.
<script src="//www.google.com/jsapi?autoload={"modules":[{"name":"search","version":"1"}]}"> </script>
- הקוד שלנו להדפסת קוד בצורה נעימה ו-Modernizr נכללו בכל דף, גם אם אף פעם לא השתמשו בהם. Modernizr נהדר, אבל הוא מפעיל כמה בדיקות בכל טעינת דף. חלק מהבדיקות האלה מבצעות שינויים יקרים ב-DOM ומאטות את טעינת הדף. עכשיו אנחנו כוללים את הספריות האלה רק בדפים שבהם הן נחוצות בפועל. -2 בקשות :)
שיפורים נוספים בביצועים:
- העברנו את כל ה-JavaScript לתחתית הדף (אם אפשר).
- הוסרו תגי
<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
.
Application Cache
בגרסה לנייד של html5rocks נעשה שימוש בApplication Cache כדי לזרז את הטעינה הראשונית ולאפשר למשתמשים לקרוא תוכן במצב אופליין.
כשמטמיעים את AppCache באתר, חשוב מאוד לא לשמור בקובץ המניפסט (באופן מפורש בקובץ המניפסט עצמו או באופן משתמע באמצעות כותרות בקרה כבדות של מטמון). אם הדפדפן מאחסן את המניפסט במטמון, תהיה לכם עבודה קשה לנפות באגים. מערכת 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 והתמונות החשובים. הדבר האחרון שתרצו לעשות הוא לאלץ את הדפדפן בנייד להוריד מספר גדול של נכסים בכל עדכון של 'אחסון מטמון לאפליקציות'. במקום זאת, חשוב לזכור שהדפדפן יאחסן בדפים מטמון באופן משתמע דף HTML כשהמשתמש יבקר בו (והוא כולל מאפיין <html manifest="...">
).