2012-04-22

טרנדים חמים בתחום ה Web וה Mobile - חלק 2

בהמשך לפוסט הקודם בסדרה, טרנדים חמים בתחום ה Web וה Mobile - חלק 1, הנה עוד טרנדים חמים בתחום הווב והמובייל:

Unit Testing ל JavaScript
אין פה משהו חדש לגמרי: מי שבאמת רצה, יכול היה לכתוב unit tests לקוד ה JavaScript עוד מזמן. עד לא מזמן Unit Tests היו נפוצים בעיקר בצד השרת ומעט מאוד בצד הלקוח. מה שהשתנה הוא הפיתוח הרב שנעשה למובייל, שעבורו פתרונות כמו GWT, פלאש או IceFaces - כבר אינם טובים מספיק.

העיקרון דומה למדי ל Unit Tests בצד השרת, מלבד העובדה שהשונות בין סביבות הריצה היא רעש לא קטן. בעוד שלג'אווה יש JVMים רבים, יכולתי בתור מפתח לבדוק את הקוד שלי על JVM של Windows (רץ ב IDE וב CI) ולהניח שהוא ירוץ בצורה זהה על שאר הפלטרפורמות הנפוצות. את רוב ה JVMים הקיימים מייצרת סאן אורקל והם דומים למדי. במצב נדיר בו הקוד שלכם אמור לרוץ, נאמר, על Z/OS (מערכת הפעלה של יבמ למיינפריים) אזי עליכם להתמודד עם JVM של יצרן אחר (יבמ) וייתכנו שונויות. אני נתקלתי פעם אחת בחיי בקוד שמתנהג אחרת (סביב SoftReferences) בין JVM של סאן ל JVM של יבמ.


אם ניקח את Rhino (מנוע ה JavaScript שמגיע עם ג'אווה) ונוסיף את Env.js, ספרייה טוב של ג'ון ריזלינג (היוצר של jQuery) שמדמה את ה DOM של הדפדפן, נוכל לבצע Unit Testing שיבדקו בצורה דיי טובה את הריצה של הקוד שלנו ע"פ התקנים הרלוונטים, ובצורה בינונית למדי את הריצה של הקוד על דפדפנים אמיתיים, בגרסאותיהם השונות.

ישנם 4 מנועי ג'אווה סקריפט שמשולבים בדפדפנים נפוצים: V8 של גוגל, Spider Monkey של מוזילה, Chakra של מייקרוסופט ו SquirrelFish שרץ בספארי.
כל אלה שונים במידה מורגשת מ Rhino, ושונים גם אחד מהשני. Charka, הוא מנוע חדש שנכתב עבור IE9 והוא שונה מהמנוע של גרסאות קודמות (JScript Engine) שעדיין זמין על IE9 ב Compatibility Mode [א].

מה הפתרון?
ניתן להריץ כלי אוטומציה כמו Selenium על דפדפנים שונים כחלק מתהליך ה CI. רוצים להתקין מספר דפדפנים (בעיקר IE) על מחשב אחד? Spoon.Net הוא שירות מצויין שיעשה עבורכם את העבודה עבור תשלום של 60$ בשנה.
כלי אוטומציה פשוט ומגניב יותר שעושה את אותו הדבר הוא JSTestDriver. הוא "משתלט" על ה process של הדפדפן ולכן אמור להיות מהיר ואמין יותר מ Selenium שמתבסס על ה UI.
עבור מובייל, יש כאלו שבודקים רק על WebkitJSCore שכנראה מספיק דומה לV8 ברוב המקרים, וניתן להריץ אותו ללא הרצה של דפדפן. כלומר, הרבה יותר מהר. חפשו בגוגל "Webkit headless" כדי למצוא מגוון של פתרונות.

הנה עוד כמה ספריות שיעשו את פיתוח ה Unit Tests שלכם לקלים ומהנים יותר:
Jasmine - סביבת unit testing ו BDD, כנראה הנפוצה מכולן.
QUnit היא אלטרנטיבה מבית היוצר של ג'ון ריזלינג. יש כאלו שאומרים שהיא קצת יותר טובה, אך הקהילה שלה קטנה יותר והשוני בקוד של הבדיקות הוא דיי זניח, לדעתי.
Mocha (מבטאים כמו "מוקה") היא ספריית בדיקות נחשבת, עם הרבה פלאג-אינים ותמיכה ב Node (פרטים בהמשך).

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

בדיקות תוכנה: "אני לא סומך על עצמי, אבל אני סומך על פראנק". מקור: youtube

Hybrid Web Container או בקיצור: PhoneGap
דילמה קשה ובסיסית של פיתוח למובייל הוא הבחירה בין פיתוח אפליקציית נייטיב (native) לבין אפליקצת ווב (כלומר HTML5 ו CSS).
לאפליקציית נייטיב יש יתרון ביצועים משמעותי, היא יכולה לגשת למצלמה ולרשימת אנשי הקשר ובעזרתה ניתן לייצר חווית משתמש "יותר חלקה".
אפליקציית ווב מאפשרת לכתוב קוד פעם אחת ולהשתמש בו, עם התאמות קלות, במכשירים שונים. גם ההתאמה למסך בגודל שונה (טאבלט, Note) היא קלה יותר. אין API שיישבר בין גרסאות של מערכות הפעלה.

ישנה אופציה שלישית דיי פופולרית - ה Hybrid Web Container.
איך לצרוך PhoneGap - ה HWC הנפוץ. מקור: האתר של phoneGap

הרעיון הוא דיי פשוט: כתבו אפליקציית HTML רגילה. ה Hybrid Web Container, או בקיצור HWC, יספק לכם אפליקציית נייטיב שכל מה שהיא עושה היא לפתוח מעין iFrame ענק על על המסך שמפנה לכתובת האפליקציה שלכם.
מה היתרון בכזה תרגיל?
  • אתם יכולים להפיץ את האפליקציה שלכם בעזרת ה AppStore או Google Play - היכן שמשתמשים בד"כ מחפשים אחר אפליקציות.
  • ה HWC יחשוף יכולות native של המכשיר שלא זמינים ב HTML5 כ JavaScript API: מצלמה, אנשי קשר, גישה לקבצים מקומיים, notification (לדוגמה הפעלת רטט של המכשיר, או push messages) וכו'. הערה: כותבי HTML5 עובדים כדי לאפשר להשתמש בשירותים אלו מאפליקציות ווב - אך הפער בין המצוי לרצוי הוא עוד גדול.
  • ה HWC יאפשר לכם לכתוב custom native code (נניח שדורש חישוב מאוד יעיל) ולחשוף אותו ב JavaScript עבור החלק ה HTML-י של האפליקציה שלכם.
האם HWC הוא הטוב משני העולמות? הפתרון המושלם שייתר את שתי הגישות האחרות (נייטיב וווב)? החומר השיווקי של מפתחי ה HWC יטען שכן, אך נראה שזו תשובה לא מדויקת.

HWC מביא איתו גם חסרונות מ-2 העולמות הקיימים, למשל:
  • חווית המשתמש לא תהיה חלקה ונקיה כמו באפליקציית נייטיב (עדיין יש דפדפן).
  • התאימות לכל המכשירים לא תהיה טובה כמו אפליקציית HTML.
  • אם תעשו שינוי בnative קוד תצטרכו לשחרר גרסה חדשה דרך ה AppStore, דבר שלוקח זמן אצל אפל אפילו אם מדובר ב"תיקון אבטחה קריטי". צד ה HTML - מצד שני, יצטרך לדעת להתמודד עם הגרסאות השונות של ה Container מכיוון שאין לכם שום דרך להכריח את המשתמשים לשדרג את ה Container.
בקיצור, HWC היא אופציה שלישית ואטרקטיבית - אך אינה בהכרח אופציה נעלה. היא פשוט עוד אופציה אפשרית שכדאי לשקול.


MVC Frameworks for JavaScript
מכירים Frameworks מבוססי תבנית העיצוב MVC - Model View Controller? אני מדבר על Struts, JSF או ASP.NET MVC? אני מניח שכן.

ובכן - תשכחו מכל מה שידעתם. אנחנו נדבר על MVC ל JavaScript.

לא, לא בגלל שMVC התגלה לפתע כלא-מוצלח. להיפך. בגלל שמה שנקרא כיום "MVC Framework for JavaScript" - הוא פשוט לא MVC במובן שאתם מכירים. העקרונות דומים, אך הצורך העיקרי איננו עוד בשליטה בניווט בין דפים. לדקדקנים: מדובר יותר ב MVP או MVVC - תבניות עיצוב שמתארות בצורה מדוייקת יותר את מה ש Frameworks אלו מספקים. בקיצור ניתן לומר שמדובר ב *MV, שיש בהם אלמנטים דומים ל MVC.

MVC קלאסי מבוסס על 2 עקרונות מרכזיים:
  • הראשי: הפרדה בין UI ל Business Logic, או מה שנקרא View ל Model. זו הפרדה חשובה מאז ומעולם. הקשר בין ה View ל Model יהיה לרוב ע"י Value Objects בלבד, מה שנקרא בג'אווה Beans.
  • המשני: העברת פעולות ה navigation בין הדפים למקום מרכזי (ה controller). במקום שכל דף יכיר את הדפים אליהם אפשר לנווט ממנו - הוא מכיר רק פעולות, וגורם שלישי מרכז את הפענוח וההפניה ליעד האמיתי. לעתים קרובות בעזרת קומפיגורציה שאפשר לשנות ללא כתיבת קוד או תלוית הקשר, משתמש למשל.
ה Framework הנפוץ ביותר ה Backbone.js. זהו "*MV של JavaScript" ללא Controller שמבצע ניווט בין דפי ווב. גם ההפרדה בין UI ל Business Logic היא given - אך היא לא העיקר. היכולת העיקרית שלו היא לסייע בכתיבת אפליקציות "דף אחד" עם אלמנטים דינמיים מתחלפים.

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

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

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

Backbone.js, למרות השם ה"כבד", הוא ספרייה רזה בת כ 700 שורות קוד (אם לא סופרים הערות). אפשר ללמוד אותו על בוריו בשעה-שעתיים והוא מתאים למכשירי מובייל. אם דיברנו בפוסט הקודם על Micro JS Frameworks- הרי גרסת ה minified שלו היא 16K בלבד. 

ישנם Frameworks רבים, אך ללא ספק הנפוץ שבהם הוא Backbone.js. בעולם ה .NET נפוץ יותר Knockout.js שמקדם את תבנית MVVP, שלמיטב ידיעתי, מוכרת בעיקר מפירסומים של מייקוסופט. 

עוד 2 ספריות נפוצות הן Spine.js ו Ember.js.


Node.js
חשבתם פעם בכמה שפות וטכנולוגיות מפתחי Web צריכים להתמחות? מצד אחד HTML CSS ו JavaScript, מצד שני לרוב האפליקציות זקוקים לשרת ואז צריך לכתוב ב Java, Ruby או #C. פעמים רבות, מפתחי הווב חזקים יותר בצד הלקוח ו"קצת מחפפים" בצד השרת. "לו רק ניתן היה לפתח רק ב JavaScript...".
מפתחי צד השרת (כמוני) נוטים לתעב ג'אווהסקריפט ומחפשים כל מיני דרכים להימנע ממנו (פלאש, GWT ועוד).

האם אפשר להריץ Groovy (וריאנט של ג'אווה שאני אוהב) בדפדפן? - בחלומות הלילה.
האם אפשר להריץ JavaScript בצד השרת? כן. קיימים מנועי ג'אווהסקריפט שרצים בצד השרת כמו Rhino או V8. הרשו לי להציג את קפיצת המדרגה בצד זה: Node.js.

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

אבל בכל זאת - זה קצת גימיק, לא? JavaScript עם Interpreter הוא קצת איטי. ובכלל להשוות שרת מורכב כמו Apache Geronimo לאיזו ספריית JavaScript? זה נשמע קצת לא רציני.
אז מתי אני ארצה להשתמש בפיתוח ג'אווהסקריפט לצד השרת? עבור בדיקות? עבור Prototyping?

האמת המפתיעה הוא ש Node.js הוא מהיר. מאוד מהיר.
בואו נתחיל בלהסביר ממה Node.js מורכב:
Node.js הוא (הגדרה שלי) שרת ווב שכתוב בג'אווהסקריפט. הוא רץ על V8 - מנוע הג'אווהסקריפט המהיר של גוגל (שבעצם מקפמל JIT את הג'אווהסקריפט לקוד מכונה). בנוסף יש ספריות שונות המשלימות יכולות צד שרת שחסרות  בג'אווהסקריפט (גישה לקבצים, תקשורת וכו') וספריית ניהול חבילות בשם npm (המקבילה ל Ruby Gems או Python Eggs). הכתיבה ב Node היא דיי low level, ויש להרכיב לבד את הודעות ה HTTP, אך אין מניעה להשתמש בספריות שיאפשרו רמת אבסטרקציה גבוהה יותר.

Node מול אפאצ'י - השרת המהיר של הווב. מקור: http://blog.raducojocaru.com

בעוד שרתי ווב מלפני עשור (כמו תקן ה Servlets של ג'אווה) תוכננו בראיה של הגשת דפי HTML גדולים, Node נכתב בראייה של מענה להודעות קטנות (קריאות Ajax או WebSockets), כאשר שרת HTTP מצומד מגיש את קבצי ה JavaScript או CSS ובניית ה markup נעשית בצד הלקוח. התוצאה היא טיפול בעיקר בפעולות IO (בסיס נתונים, קבצים, רשת) קצרות. כל פעולות ה I/O ב Node הן אסינכרוניות ומבוססות callbacks ברגע שפעולת ה IO הסתיימה.

למטרה זו Node מהיר בצורה ניכרת מרוב השרתים שאנחנו מכירים היום (IIS, Tomcat וכו') כאשר הוא צורך קצת יותר זיכרון ו CPU (יש Overhead לכל המקביליות הזו) אך הוא יכול לטפל במספר רב יותר של קריאות. בדיקות מסוימות מראות טיפול בפי 10 בקשות במקביל משרת Apache + PHP. המספרים המדויקים כמובן תלויים בתסריט המדויק - אך יש הרבה פוטנציאל. במצבים של גישות ארוכות שחסומות ב CPU - צפו לתוצאות משמעותית פחות מרשימות. כמו כן שימו לב שכדאי להימנע מקוד סינכרוני ולהתאים את גודל ה Connection Pool על מנת להגיע לתוצאות הרצויות על גבי Node.

את אותה ארכיטקטורה אסינכרונית ניתן כמובן לשחזר בשפות שונות. תוכלו למצוא אותה בשרת Webbit שכתוב בג'אווה, למשל.

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


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


[א] המצב ב JavaScript הוא עוד טוב. אם אתם מתעסקים בDOM ותומכים ב IE, בקרוב תצטרכו לבדוק את הקוד שלכם על 72 גרסאות שונות.
על Android תצטרכו להתמודד עם Chrome (החל מ Android 4 ועדיין לא דפדפן ברירת המחדל) או Android Browser - דפדפן מעפאן לגמרי שזמין בכל הגרסאות המוקדמות יותר של אנדרואיד. בנוסף יש לא מעט דיווחים שחומרה שונה של אנדרואיד גורמת לדפדפן ה Android Browser להתנהג קצת אחרת - דבר שלא אימתתי בעצמי.

6 תגובות:

  1. אנונימי23/4/12 13:25

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

    ההבטחות הגדולות של Node.JS הם באפליקציות\אתרים שדורשים מצד אחד חיבור קבוע ללקוח (Long polling), או חיבורים מקבילים רבים (נדרש רק THREAD אחד, בשונה מכל WEBSERVER אחר).
    בנוסף לפיתוח אתרים שדורשים עבודה בענן ומול מספר רב של אתרים אחרים (Facebook, Twitter, Linkedin, וכו') ישנם מודולים מצויינים שמאפשרים לעשות דברים שבסביבות מקבילות ידרשו זמן רב יותר משמעותית.
    ראה:
    http://stackoverflow.com/questions/5062614/how-to-decide-when-to-use-nodejs
    ו:
    http://www.mikealrogers.com/posts/a-new-direction-for-web-applications-.html

    -אבנר כ

    השבמחק
  2. היי אבנר,

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

    ליאור

    השבמחק
  3. הי, הערה בקשר ל javascript unit testing.

    אני מסכים שמנועי javascript שונים הרבה יותר אחד מהשני מאשר java virtual machines, אבל לדעתי דוגמאות על שוני ב performance ועל soft references הן דוגמאות לא רלוונטיות ל unit tests. אני הייתי שמח להבין האם לjava script יש סטנדרטים דומים ל JSR של java

    השבמחק
  4. היי ארטיום - נקודה טובה.
    באמת לא כ"כ חשוב (או סביר) ש unit tests יתארו את התנהגות ה Soft References.

    המצב בתאימות ה JavaScript הוא לא רע - אבל בטח לא טוב כמו Java. התקן המקובל הוא ECMAScript ((http://en.wikipedia.org/wiki/ECMA-262 בעוד רוב הדפדפנים (חוץ ממוזילה בערך) תומכים רשמית בגרסה 1.5 משנת 1999 ובתכונות חדשות יותר ע"פ בחירתם האישית. מוזילה תומכים ב 1.8.5 משנת 2009. הצעד הגדול הבא הוא גרסה 2.0 (שם קוד "הרמוני") שכנראה התקן שלה ישוחרר בשנה-שנתיים הקרובות. ותמיכת הדפדפנים - לא ברור.

    נאמר שיש את גרסה 1.5 עליה בכל מקרה המפתחים לרוב מסתמכים (אפשר לבדוק את קוד ה JS ב Strict Mode שעוזר לאתר סטיות מהתקן) - עד כמה טובים הדפדפנים?
    חבילת הבדיקות הרשמית היא http://test262.ecmascript.org/# והיא כוללת כ 11K בדיקות. V8 (המנוע התואם ביותר) נכשל בכ 50 בדיקות, Spider Monkey נכשל ב170 בדיקות, צ'אקרה ו SquirrelFish נכשלים בכ 600 בדיקות כ"א. המצב בגרסאות ישנות יותר של הדפדפנים - פחות טוב.
    דפדפן אופרה 11.5 כשיצא, למשל - היה נכשל בכ 3000 בדיקות (יש לו מנוע JS משלו). המצב היום הוא כבר דיי טוב.

    עד כמה זה מדוייק עבור Unit Tests? אני מניח שזה עניין של טעם אישי.

    השבמחק
  5. עוד כמה קישורים מעניינים:

    http://www.opalang.org/ - סביבה שמאפשרת שפה אחידה אחת לפיתוח ווב מבסיס הנתונים עד הדפדפן. מעניין!
    http://vertx.io/ - ספרייה ל JVM לפיתוח "Servlets" א-סינכרוניים נוסח node.js. כולל דוגמאות ברובי, גרובי וג'אווהסקריפט.

    השבמחק
  6. בקרוב יפתח קורס backbone.js כולל לימוד testing בתל אביב

    פרטים נוספים: http://backbonecourse.blogspot.co.il/
    אילן - 0547880094

    השבמחק