8 אוספים של אנימציות CSS3 שיוסיפו חיים לאתר שלכם

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

הנה דוגמה פשוטה מאוד (העבירו את העכבר על הריבוע האדום):

JS Bin on jsbin.com

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

Hover.css

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

האנימציות ב-Hover.css מחולקות לקטגוריות לפי סוג האנימציה (אנימציות על border, על הרקע, וכד') וחלקן מתאימות, לאחר שינויים קלים בקוד, גם לשימוש במצבים אחרים כמו למשל כניסה ויציאה של אלמנט.

Hover.css
Hover.css

Animate.css

אחת הספריות הותיקות יותר היא Animate.css המציעה כמה עשרות אנימציות המיועדות בעיקר לכניסה ויציאה של אלמטים מהמסך. Animate.css כוללת קבוצת אנימציות מגניבות בשם Attention Seekers (מושכי תשומת לב), המכילה אנימציות מגניבות כמו RubberBand (גומייה), שיתנו לאלמטים שלכם תחושה מציאותית וקלילה.

Animate.css

 

Animatable

ספריית Animatable היא למעשה הדגמה של אוסף כל תכונות ה-CSS התומכות באנימציה. נכון לכתיבת שורות אלו, הספרייה מציגה 39 אנימציות, שכל אחת מהן מוגדרת על מאפיין CSS אחר – שימושי מאוד כדי לקבל רעיונות חדשים לאנימציות או לדרכים בהן ניתן לממש אנימציה מסויימת.

טיפ קטן – לחצו על הכפתור "Animate all".

Animatable

SpinKit

כשהגיחה אל חיינו טכנולוגית AJAX בתחילת שנות האלפיים, כולנו למדנו להכיר את אנימציות טעינת הדף – הספינרים (spinners). הכוכבים המסתובבים האלו אמנם החלו את דרכם כתמונות gif פשוטות, אך היום קיימים ספינרים מורכבים מאוד הממומשים באמצעות אנימציות CSS, ולעתים בעזרת עשרות או מאות שורות קוד. האתר SpinKit הוא אוסף מדהים ושימושי של אנימציות טעינה שונות ומגוונות, חלקן כל כך יפות שפשוט יש חשק לגרום לדפים להיטען לאט יותר :)

SpinKit
SpinKit

Effeckt.css

לא, זוהי לא שגיאת כתיב. ספריית Effeckt.css אוספת אנימציות CSS המיועדות לתרחישים ספציפיים ונפוצים כמו: כפתור submit, הוספה לרשימה, גלילת רשימה, כותרת לתמונה ועוד. שימושי מאוד למי שמחפש להוסיף קצת חיים לקונטרולים הסטנדרטיים והמשעממים שקיימים כמעט בכל אפליקציית web.

Effeckt.css

Bounce.js

ספריית Bounce.js היא ספריית Javascript המאפשרת לנו לייצר אנימציות CSS ע"י ממשק נוח ופשוט (יחסית). הכח האמיתי של הספרייה הוא הקלות בה ניתן ליצור אנימציות מורכבות ע"י שילוב של מספר מאפייני CSS שונים במקביל, וצפיה מיידית בתוצאות. בנוסף הספרייה מכילה מספר שילובים מוכנים מראש שניתן להתחיל מהם.

Bounce.js

CSS Shake

כשמה כן היא, ספריית CSS Shake מספקת אחת עשרה אנימציות שונות עם מטרה אחת בלבד – להרעיד דברים! אני בעצמי עדיין לא בטוח מה עושים איתה, אבל היי – תודו שתמיד חלמתם לגרום ל-div לרעוד 😉

CSS Shake

CSS3 Animation Cheat Sheet

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

CSS3 Animations Cheat Sheet

 

שימוש בפונט להצגת אייקונים באתר שלכם

בשנים האחרונות הפך הטרנד של "עיצוב שטוח" (flat design) לנפוץ במיוחד. אחד המאפיינים הבולטים של גישה עיצובית זו, בעיקר באפליקציות web, הוא השימוש באייקונים מונוכרומטיים (בעלי צבע אחד). דוגמה שכרגע נמצאת לי מול העיניים היא מערכת הניהול של wordpress:

Flat icons
אייקונים מונוכרומטיים

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

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

SVG – תמונה וקטורית

Smart Vector Graphics, או SVG הוא פורמט תמונה וקטורי (vector) מבוסס XML. לא ארחיב עליו כאן, אך אקצר ואסביר שבשונה מפורמטים כמו Bitmap או JPEG, קובץ SVG לא מכיל מידע אודות הפיקסלים שבתמונה, אלא מתאר את האלמנטים השונים המרכיבים את התמונה כגון קווים, צורות, טקסט וכד'. הנה דוגמה לקובץ SVG.

לשימוש ב-SVG ישנם מספר יתרונות על שימוש בפורמטים שאינם וקטורים:

  • ניתן לשנות את גודל התמונה ללא פגיעה באיכות
  • קובץ התמונה הוא לרוב קטן יותר, במיוחד עבור תמונות פשוטות
  • ניתן לשנות את העיצוב באמצעות CSS
  • הקובץ הוא בפורמט טקסטואלי וניתן לייצר אותו דינאמית ואף להטמיע אותו ישירות ב-HTML

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

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

למזלנו, קיים פתרון שימושי ביותר לבעייה זו:

פונט אייקונים

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

קם חכם ואמר – מדוע צריכים הפונטים להכיל אותיות בלבד? למה שלא נייצר פונט המכיל, במקום אותיות, אייקונים? ואכן קיימים מספר פונטים שהם למעשה אוסף של אייקונים, ביניהם Font Awesome ו-Ionicons.

לפונט אייקונים יתרונות רבים:

  • בקשת HTTP אחת, ללא תלות במספר האייקונים אותם אנו צריכים.
  • תמיכה לאחור גם בדפדפנים ישנים מאוד (IE6).
  • ניתן לשנות את עיצוב האייקונים בנקל ע"י מאפייני CSS לעיצוב טקסט: font-size, color וכד'
  • השימוש בפונטים אלו הוא פשוט מאוד, ומצריך 2 שורות קוד בלבד:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<i class="fa fa-camera-retro"></i>

השורה הראשונה מייבאת את קובץ ה-CSS של Font Awesome (שבתורו מייבא את הפונט עצמו), והשניה מייצרת תגית ריקה, שהחלק החשוב בה הוא המאפיין class, ה"ממלא" את התגית בתוכן המתאים מתוך הפונט (גם כאן לא נגלוש לפרטים).

וכך זה נראה:

JS Bin on jsbin.com

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

Fontello

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

  • ע"י בחירה ממבחר קיים של מאות אייקונים מפונטים נפוצים כגון Font Awesome, Fontelico, Entypo ועוד.
  • ע"י העלאה של קבצי SVG משלנו.

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

<link rel="stylesheet" href="path/to/fontello.css">
<i class="icon-like"></i>

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

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

3 טריקים ב-CSS שאני מאוד אוהב

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

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

Negative Margin

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

.myelement {margin-top: -20px;}

היופי ב-negative margin הוא שבשונה משיטות אחרות למיקום אובייקט, שוליים שליליים למעשה מקטינים את השטח שתופס האובייקט ב-flow, אבל עדיין משאירים אותו בתוך ה-flow.

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

JS Bin on jsbin.com

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

Border Box

נניח שאנחנו רוצים שאובייקט מסויים יהיה ברוחב כולל של 200px, ובנוסף שיהיו לו padding ו-border. לפי מודל הקופסה של CSS, בו רוחב האובייקט לא כולל את ה-padding וה-border, אנחנו צריכים לחסר אותם מהרוחב הסופי כדי להגיע אליו במדוייק:

div {
  width: 156px; /* 200 - 40 - 4 */
  padding: 20px;
  border: 2px solid #000;
}

אך מה אם אין לנו את הגודל המדוייק בפיקסלים (למשל אם הגודל הוא באחוזים)? כאן אנחנו כבר בבעיה. אפשר אמנם להשתמש ב-calc:

div {
  width: calc(50% - 40px - 4px);
  padding: 20px;
  border: 2px solid #000;
}

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

box-sizing: border-box;

שורה זו תגרום למאפיינים width ו-height להתנהג מעט שונה, ובמקום לקבוע את הגודל של תוכן האובייקט בלבד (ללא ה-padding וה-border), הם יקבעו את התוכן כולל פרמטרים אלו. שימו לב לדוגמה הבאה: JS Bin on jsbin.com

ניתן לראות שלמרות שלאובייקט הראשון קבענו padding ו-border, הרוחב הכולל שלו הוא עדיין 200px, בדומה לאובייקט השני שלא מוגדרים עבורו מאפיינים אלו. נסו לשחק עם הדוגמה, למחוק את המאפיין box-sizing ולראות מה קורה.

Relative Sizing

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

העיקרון הוא פשוט – במקום להשתמש ביחידות גודל אבסולוטי בקוד ה-CSS (בד"כ px), נשתמש ביחידות גודל יחסי, em (אפשר גם אחוזים).

em היא יחידה שגודלה הוא ה-font-size של האובייקט הנוכחי. כלומר במקרה הבא:

span {
  font-size: 16px;
  margin-bottom: 1em;
}

לאובייקט שיווצר יהיו שוליים תחתונים ברוחב 16 פיקסלים. ומה יקרה אם נשנה את גודל הפונט ל-18px? ניחשתם נכון – גם רוחב השוליים ישתנה בהתאמה.

כמובן שאפשר שגם ה-font-size עצמו יהיה יחסי:

body {
  font-size: 16px;
}

span {
  font-size: 0.75em;
  margin-bottom: 1em;
}

במקרה זה רוחב השוליים התחתונים של span יהיו 16 כפול 0.75 כפול 1, שהם 12 פיקסלים.

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

body {font-size: 16px;}

כל שאר הגדלים בקוד שלנו יהיו תמיד יחסיים, כלומר ביחידות em או באחוזים. למשל אם נרצה ליצור כותרת בגודל 20px, נוכל לחשב את הגודל ב-em ע"י חלוקה ב-16 (גודל הפונט הדיפולטי), כלומר 20px יהיו 1.25em.

באופן זה ע"י שינוי גודל הפונט במקום אחד בלבד (ב-body), למעשה נכווץ את כל הגדלים באתר שלנו, עם שמירה על יחס. כעת נוכל להגדיר media queries שיעשו את זה באופן הבא:

@media screen and (min-width: 1024px) {
  body {font-size: 14px;}
}

@media screen and (min-width: 800px) {
  body {font-size: 12px;}
}

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

אגב, זה לא אומר שמעכשיו חובה להגדיר ידנית את גודל הפונט של כל התגיות בעמוד. זאת מכיוון שבכל הדפדפנים, כל גדלי ברירת המחדל מוגדרים גם הם ב-em, למשל גודל הפונט של h1 הוא לרוב 2em, ושוליים עליונים ותחתונים של p הם 1em.

תהליך בנייה לקוד צד לקוח – למה צריך את זה ואיך מייצרים אחד?

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

  • שפות מתקמפלות, כגון c ונגזרותיה, Java, ועוד. שפות אלו מצריכות תהליך הידור (קומפילציה), הממיר אותן לקוד בשפה נמוכה יותר כגון שפת מכונה או שפת ביניים, אותה ניתן להריץ ישירות על מכשירי היעד.
  • שפות סקריפט, כגון Python, PHP, Javascript וכד'. שפות אלו לא צריכות קומפילציה, והקוד שלהן נשלח כמו שהוא לשטח, שם הוא מורץ ע"י interpreter.

לאחרונה הגבול בין שתי הקבוצות החל להיטשטש. ניקח לדוגמה את פייסבוק, שם כתבו מערכת להמרת קוד ה-PHP שלהם לקוד C++ לטובת שיפור ביצועים. גם אם הקוד עדיין מפותח בשפת סקריפט, בפועל הוא מומר ומורץ בשטח כקוד בשפה אחרת. התהליך האוטומטי המבצע פעולות על הקוד כדי להכינו לפרודקשן נקרא תהליך בנייה (בִּילְד).

במאמר זה נתמקד בתהליך בנייה עבור קוד צד לקוח (Front End) הכתוב בשפות Javascript, CSS ו-HTML, נבין איך תהליך כזה עוזר לנו, ונכיר טכנולוגיות העוזרות לנו לממש אותו.

למה צריך תהליך בנייה לקוד צד לקוח?

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

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

איחוד קבצי קוד

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

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

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

טרנספילציה

כאשר משתמשים בשפות הנגזרות מ-Javascript כגון CoffeeScript, JSX או Dart, רצוי להמיר את הקוד ל-JS לפני ההעלאה לאתר ולא בזמן הריצה (אחרת יש צורך בטעינת ספריות js נוספות והרצתן). תהליך ההמרה, הנקרא טרנספילציה או טרנסקומפילציה, מבוצע בתהליך הבנייה, וניתן לבצע אותו גם עבור שפות המומרות ל-CSS כגון less או Sass.

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

מזעור נפח הקוד

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

כלים רבים, ביניהם Closure Compiler, UglifyJS ו-Clean-css, ממזערים את הקוד ע"י שיטות שונות כמו הסרת רווחים מיותרים, שינוי שמות משתנים מקומיים, מחיקת הערות ועוד, וזאת ללא פגיעה בתפקוד הקוד. כלים אלו גם יוודאו את תקינות הקוד ויציפו שגיאות תחביר.

לדוגמה, נניח שהקוד שלנו נראה כך:

// A simple function.
function hello(longName) {
  alert('Hello, ' + longName);
}
hello('New User');

לאחר הרצה של Closure Compiler כחלק מתהליך הבנייה, הקוד ימוזער לקוד הבא, הקצר ממנו בחצי:

function hello(a){alert("Hello, "+a)}hello("New User");

מדובר בחיסכון של 50% מנפח הקוד, שיכול להגיע למאות KB ואף יותר באפליקציות גדולות.

ניתוח סטאטי של הקוד

ישנן טעויות רבות בקוד שניתן לגלות בנקל ע"י מעבר אוטומטי על הקוד:

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

כמעט עבור כל שפות התכנות קיימים כלים המבצעים ניתוח סטאטי של הקוד ומגלים את השגיאות הנ"ל ועוד רבות אחרות. עבור JS ו-CSS ניתן להשתמש בכלים JSHint ו-CSS Lint בהתאמה.

שינוי שם קובץ הקוד הסופי

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

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

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

כמובן שתהליך קביעת שם הקובץ מתבצע אוטומטית בתהליך הבנייה, כמו גם עדכון קבצי ה-HTML המתאימים כך שידעו איזה קובץ לטעון. הכלי שאני משתמש בו הוא gulp-rev, הקובע את שם הקובץ לפי חישוב hash על הקוד.

הרצת בדיקות אוטומטיות

במידה וכתבנו בדיקות אוטומטיות, נרצה להריץ אותן לפי העלאת הקוד לאתר.

איך מייצרים תהליך בנייה?

במידה ותהליך הבנייה שלכם פשוט ומכיל שלבים בודדים בלבד, תוכלו לממש אותו בעצמכם בשפת הסקריפט המועדפת עליכם, או אפילו ע"י shell script. אך עבור תהליכים מורכבים יותר, קיימים כלים יעודיים ומעולים שנכתבו למטרה זאת, רובם מבוססי Node.js. (שימו לב – זה לא אומר שאתם צריכים שרת Node.js כדי להריץ את האתר שלכם, אלא רק להתקין Node.js על מחשב הפיתוח). שני הכלים הנפוצים ביותר נכון לכתיבת שורות אלו הם:

Grunt

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

Grunt מבוסס על קונפיגורציה, כלומר לאחר התקנת הפלאגינים הדרושים, תצטרכו להגדיר מה אתם רוצים לעשות באמצעות JSON, בקובץ JS הנקרא Gruntfile. דוגמה לקובץ Gruntfile המריץ את Uglify Js:

grunt.initConfig({
  pkg: grunt.file.readJSON('package.json'),
  uglify: {
    options: {
      banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
    },
    build: {
      src: 'src/<%= pkg.name %>.js',
      dest: 'build/<%= pkg.name %>.min.js'
    }
  }
});

Gulp

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

gulp.task('css_lint', function() {
 return gulp.src(['src/main.less'])
   .pipe(csslint('./.csslintrc'))
   .pipe(csslint.reporter())   
   .pipe(concat(module_name + '.css'))   
   .pipe(autoprefixer());
});

אני אשאיר לכם את הבחירה בין השניים, אך אציין שהבחירה האישית שלי היא Gulp, מכיוון שהוא חדש יותר, ולדעתי התחביר שלו נוח יותר.

דוגמה לתהליך בנייה מלא

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

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

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

 

6 טכניקות שיזניקו את קוד ה-web שלכם אל העתיד

אחת הבעיות המעיקות ביותר בפיתוח web, בין אם מדובר באתר פשוט או ב-web app מורכב, היא חוסר התמיכה של דפדפנים שונים בסטנדרטים חדשים של HTML, CSS ו-Javascript. בשנים האחרונות שפות אלו מתפתחות בקצב מסחרר, וליצרני הדפדפנים השונים קשה לעמוד בקצב. אנחנו כמפתחי web לרוב נרצה שהאתר שלנו יעבוד כמו שצריך על כל הדפדפנים הפופולאריים, אך לעיתים אפילו הגרסאות החדשות ביותר שלהם (שלא נדבר על גרסאות קודמות…) חסרות תכונות בסיסיות, מה שהופך תכונות אלו בפועל ללא שמישות.

לדוגמה, תחביר חדש ושימושי של javascript הוא arrow functions:

var func = (x, y) => x + y - 1;
func(3, 4); // 6

נכון לכתיבת שורות אלו השימוש ב-arrow functions לא אפשרי ב-Internet Explorer (באף גרסה), ואף יגרום ל-syntax error. הדבר מונע לחלוטין שימוש ביכולת זו באתר שאמור לתמוך ב-IE (אלא אם בוחרים להתעלם מבערך 10% מהגולשים שלנו).

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

#1 – הכרת השטח

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

Can I use

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

למשל בתמונה למעלה ניתן לראות ש-CSS3 3D Transforms נתמכים בכל הדפדפנים למעט IE בגרסה 9 ומטה ו-Opera Mini. כעט ניתן להחליט האם להשתמש בפיצ'ר זה ולפגוע בנראות האתר בדפדפנים הישנים או לא.

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

ECMAScript Compatibility Table

בשונה משפות תכנות קונבנציונליות שיוצאות לשוק בגרסאות, Javascript, או בשמה החדש ECMAScript, היא אוסף גדול של יכולות בלתי תלויות. כל פלטפורמה (דפדפן, mobile os, מנוע JS) בוחר לממש חלק מהפיצ'רים האלו בסדר שרירותי כלשהו, כלומר תמיכה ביכולת אחת לא בהכרח מעידה על תמיכה באחרת.

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

ECMAScript Compatibility Matrix
ECMAScript Compatibility Matrix

בדומה ל-Can I use, ניתן להשתמש במידע זה כדי להחליט באילו יכולות שווה לנו להשתמש, באילו לא, ולאילו אפשר לחפש חלופות.

#2 – Transpiling

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

Javascript Transpilers

קיימים מספר טרנספיילרים עבור javascript, והמועדף עליי הוא Babel (בעבר 6to5). כלי זה ממיר שימוש בפיצ'רים חדשים של JS לקוד המבצע את אותה פעולה בדיוק (או בערך), אך ע"י שימוש בקוד JS הנתמך בכל הדפדפנים והפלטפורמות.

כמו שניתן לראות כאן, נכון לכתיבת שורות אלו, מבין כל פלטפורמות ה-JS השונות Babel תומך כמעט במספר הרב ביותר של פיצ'רים (שני רק ל… Edge?!), מה שמבטיח לנו שכמעט כל יכולת חדשה של JS שנשתמש בה תעבוד על כל הדפדפנים.

CSS Transpilers

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

div {
  appearance:button;
  -moz-appearance:button; /* Firefox */
  -webkit-appearance:button; /* Safari and Chrome */
}

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

תהליך בנייה

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

#3 – Polyfills

יכולות מסויימות של Javascript או HTML הן מורכבות מדי כדי לממש בתוך טרנספיילר, למשל SVG, Canvas, HTML Storage ועוד. כדי שבכל זאת נוכל להשתמש בהן, נכתבו עבורן תחליפים עבור דפדפנים ישנים. תחליפים אלו נקראים polyfills (ולעיתים shims). קיימים Polyfills כמעט עבור כל תכונה חדשה של HTML או JS, ורשימה די מקיפה שלהם ניתן למצוא כאן.

ברוב המקרים polyfill לא ירוץ אם הוא יזהה שהיכולת שהוא אמור להחליף כבר קיימת בדפדפן הנוכחי, ולכן זה בטוח להכיל את ה-polyfills בקוד שלנו תמיד. אך שימו לב ש-polyfills הם בסופו של דבר קוד JS, ושימוש מופרז בהם יכול להגדיל את הקוד שלכם משמעותית. אם לא אכפת לכם לבצע בקשת HTTP נוספת, תוכלו להשתמש בשירות polyfills.io, המוריד את ה-polyfills הנדרשים לפי ה-user agent של הדפדפן, וכך יכול לחסוך רוחב פס יקר.

#4 – זיהוי בזמן אמת ומימוש חלופות

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

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

לאחר ריצה של כל בדיקה תתווסף מחלקה (class) לתגית ה-html של האתר שלכם, שתאפשר לכם לבנות התנהגות שונה, אפילו בקוד ה-CSS עצמו, במידה ויכולת מסויימת ממומשת או לא. כמובן שניתן לגשת לתוצאות הבדיקות גם באמצעות JS.

#5 – בדיקות, בדיקות, בדיקות

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

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

  • אתרים כמו Browsershots (ויש עוד עשרות כאלו) יצלמו עבורכם את האתר שלכם בכל דפדפן שתבחרו. כך תוכלו לזהות במהירות היכן יש בעיות נראות לעין ולהתמקד בדפדפנים הבעייתיים.
  • השירות BrowserStack מאפשר לכם להתחבר לעשרות גרסאות של דפדפנים על כל סוגי מערכות ההפעלה (כן, גם מובייל) ולבדוק בפועל את האתר שלכם עליהם. ניתן אפילו לבדוק את האתר כאשר הוא רץ על המחשב שלכם!!
  • אם אין לכם כח לבדוק ידנית כל פעם, ואין לכם צוות QA פנימי, חברת Rainforest QA מספקת שירותי QA as a Service, ומאפשרת לכם להגדיר בדיקות ידניות, שיבוצעו ע"י בודקים אנושיים באופן מיידי. אגב, הם משתמשים ב-Mechanical Turk.
  • ואם יש לכם קצת זמן פנוי, אולי שווה לכם לכתוב בדיקות אוטומטיות באמצעות Selenium. ישנם שירותים (BrowserStack ביניהם) המאפשרים לכם להריץ את בדיקות ה-Selenium שלכם בענן על עשרות דפדפנים שונים.

#6 ואחרון – ניטור שגיאות

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

אך זה שמשהו קורה אי שם אצל הלקוח לא אומר שאי אפשר לדעת עליו ולטפל בו!

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

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

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

לסיכום

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