יום שני, 28 בינואר 2013

ביצועים של אפליקציות ווב: הרשת

לשעבר: "המדריך לטרמפיסט: הצד האפל של ביצועי אפליקציות ווב".

בפוסט הקודם, ביצועים של אפליקציות ווב: מבוא לצד האפל, התבוננו בהשפעה המשמעותית של הרשת על ביצועי אפליקציות הווב. ראינו ש ל-Bandwidth כיום חשיבות פחותה, ושצוואר הבקבוק האמיתי הוא ה-Latency - משהו שמאוד קשה לשפר ברמת התשתיות. כמו כן ראינו שהמצב חמור יותר ברשתות 3G של מובייל, שם ה Latency לעתים כפול מזה של הרשת הקווית.

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

פוסט זה מתארח בסדרה: אבני הבניין של האינטרנט.




מקביליות בטעינת Resources

כפי שראינו בפוסט הקודם, טעינה של אפליקציית ווב מורכבת מעשרות, אם לא מאות, קריאות HTTP.
מדוע, בעצם, יש כ"כ הרבה קריאות?
  1. אנו נוהגים לכתוב את האפליקציות בצורה מודולרית ולחלק את הקוד להרבה קובצי javaScript ו CSS.
  2. אנו משתמשים בספריות עזר, שכוללות עוד קבצי javaScript ו CSS.
  3. אנו משתמשים בהרבה תמונות: קצבי jpeg, png וכו'
  4. לעתים משתמשים ב Template Engines ואז מייצגים כל Template כקובץ HTML נפרד.
  5. אנו מוסיפים לאתרים / אפליקציות כפתורי שיתוף סוציאליים (Facebook Like או "1+"), ווידג'טים (כמו Outbrains) או כלי אנליטקס - כל אחד הוא לרוב קובץ javaScript וקובץ CSS.
  6. אנו מבצעים קריאות Ajax לשרת(ים) בכדי להביא מידע.
  7. פרסומות
ועוד....

ניתוח בעזרת (Firebug (FF Plugin של טעינה של הדף הראשי באתר Ynet. מעל 350 קריאות לשרת.
אתר Ynet הוא דוגמה קצת קיצונית אך אמיתית לגמרי. למרות ריבוי הקריאות, האתר נטען בזמן נסבל (11 שניות) כשה-cache קר [א]. זמן "סביר" זה הוא בזכות Latency נהדר ש Ynet נהנה ממנו: כ 20-30ms בחיבור מספק כבלים בישראל. גישה ממדינה אחרת הייתה מספקת חוויה אחרת לגמרי.
ייתכן (אני לא יודע) ש Ynet משתמשים בשירותי CDN על מנת לשמור על Latency כ"כ טוב. לעתים יותר זול לשכור שירותי CDN מאשר לשנות את הקוד של האתר למבנה יותר אופטימלי. זו החלטה עסקית לגיטימית.
כשיש לנו כ +300 קריאות HTTP, דיי ברור שמיקבול הקריאות יכול לגרום לשיפור מאוד משמעותי. רוב הדפדפנים המודרנים פותחים במקביל כ 6 TCP Connections ל host על מנת להוריד קבצים (6 לכל הטאבים ביחד, אם אני זוכר נכון).

מדוע, אם כן, לא לפתוח 10, 20 אולי אפילו 40 connections מקביליים?

סיבה ראשונה: הסכנה להעמיס על השרתים יתר על המידה ולגרום בלי כוונה ל Denial of Service. שרתים קלאסיים (למשל JEE) דורשים משאבים רבים לכל connection שמוחזק פתוח. אם הדפדפנים יפתחו עשרות connections מול כל שרת, הם עלולים להשבית שרתים רבים. ע"פ תקן ה HTTP (מקור: RFC2616, עמ' 46) אין לפתוח יותר מ 2 connections במקביל ל Host יחיד - כלל שכל הדפדפנים כבר היום חורגים ממנו.

סיבה שנייה: (ואולי יותר חשובה) הצורה בה עובד פרוטוקול TCP.
לפרוטוקול TCP יש מנגנון שנקרא TCP Congestion Control, או בצורה יותר עממית: "Slow Start" ("התחל חלש"). ל TCP אין שום מידע על מהירות החיבור של הלקוח (כלומר מה ה Bandwidth הפנוי אליו) ועל כן הוא מתחיל לאט, ומעלה את הקצב בהדרגה. על כל הודעה שהוא שולח הוא מצפה לאישור (הודעת acknowledge). ברגע שהוא מפסיק לקבל אישורים על אחוז מסוים מההודעות, הוא מניח שהוא הגיע ל Bandwidth המרבי ומייצב את קצב ההעברה [ב]. במילים אחרות, ניתן לומר של TCP Connection לוקח כמה שניות "להתחמם" ולהוריד מידע בקצב מרבי.
״התחממות״ שאורכת מספר שניות איננה בעיה בהורדת קובץ של כמה GB - שאורכת כשעה, אבל זו בעיה כאשר רוצים לטעון אתר בשניות בודדות: פתיחת 40 connections מקביליים משמעה 40 connection שלא יספיקו ״להתחמם״ ולנצל את ה Bandwidth האמיתי שקיים.



טקטיקה: מקביליות בעזרת ריבוי Hostnames

טכניקה אחת לשיפור זמני הטעינה של אתר האינטרנט היא לחלק את הקבצים של האתר לכמה hosts שונים. לדוגמה:
yent.co.il ו images1.ynet.co.il, על מנת לגרום לדפדפן לפתוח יותר TCP connections במקביל: נאמר 12 במקום 6.
כפי שכבר הבנו, "תכסיס" זה יוצר trade-off בין מקביליות, למהירות ה TCP Connections.

מקובל כיום להאמין ש 6 TCP Connections היא נקודת האיזון האופטימלית בין השניים. טכניקה של ריבוי Hostnames הייתה בעלת משמעות בתקופה שדפדפנים פתחו רק 2-3 connections ל Host יחיד. כיום, הדפדפנים כבר התיישרו לנקודת 6 ה connections ל Host, ועל כן טכניקת ריבוי ה hostnames נחשבת כמיותרת ולרוב לא יעילה - שלא לדבר על הסרבול שבמימוש שלה.

כדאי להזכיר שוב את החשיבות של מנגנון ה "HTTP "Keep-Alive באספקט זה: שימור TCP connection לא רק חוסך את ה Three way handshake, אלא גם שומר על ה Connection "חם".

דפדפנים מסוימים שומרים את ה TCP Connections פתוחים עוד כמה שניות בכדי לא "לאבד" Connection "חם" בציפייה לקריאת Ajax שעוד מעט תבוא.

טכניקה הופכית לטכניקה הנ"ל, היא לארח באתר שלכם כמה Scripts ו CSS של ספריות חיצוניות, במקום להפנות לאתר המקורי שמארח אותן וכן להינות מה Connections ה"חמים".
גם כאן יש Trade-off לא טריוואלי: נניח ואתם בוחרים לארח קובץ מאוד נפוץ, לדוגמה ה Script של כפתור ה "Like" של פייסבוק: במקום לקרוא את הקובץ מ

http://facebook.com/like-button-script.js

אתם מביאים אותו מ:

http://mysite.com/like-button-script.js

נוצרת בעיה: ה browser cache עובד ע"פ absolute URI ולכן במקום לקחת את הקובץ שכבר נמצא ב cache ע"פ ה URI של פייסבוק, הדפדפן יטען את הקובץ מחדש מהאתר שלכם. זכרו: ה roundtrip הכי זול הוא ה roundtrip שלא קרה.

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


טקטיקה: Minification

טכניקה נפוצה למדי לשיפור ביצועים של אפליקציות ווב היא "לדחוס" את קובצי ה javaScript ו/או CSS, בתהליך שנקרא minification, crunching או לעתים אף uglification :). קבצים קטנים יותר --> נוכל להעביר קבצים יותר מהר ב 6 ה Connections שלנו.

minification היא דחיסה שלא משנה את תוכן הקובץ, אלא רק מצמצמת אותו. למשל בג'אווהסקריפט: הסרת רווחים והערות, קיצור שמות משתנים (שאינם public) ואפילו הסרת סימני "נקודה פסיק" שה minifer יודע לחזות שהדפדפן ישלים ויתקן בצורה נכונה. הקובץ הוא עדיין קוד JavaScript תקני שהדפדפן מסוגל להריץ כפי-שהוא.

לדוגמה, קטע קוד הבא:

מצומצם ל:

קבצי javaScript נדחסים לרוב בין 50% ל 90% (כאשר יש המון הערות). קבצי CSS נדחסים לרוב בין 30% ל 50%.

לזכות טכניקת ה minification ניתן לומר שהיא פשוטה ליישום: פשוט מוסיפים עוד שלב ב build שיידחוס את הקבצים.
הכלים הם רבים וסטנדרטיים: YUI Compressor של יאהו!, Closure Compiler של גוגל או CSSO לדחיסת קבצי CSS.
דחיסת קבצי javaScript מסוגלת לעתים להסיר קוד שלא בשימוש, וכך לחסוך זמן CPU של הדפדפן על פענוח וטעינת קוד JavaScript מיותר.

קושי
נניח שהכנסנו כלי Minification לתהליך ה Build שלנו וראינו שיפור ביצועים - נהדר. הבעיה: מה קורה כאשר אנו רוצים לבצע Debug?
כמעט ובלתי אפשרי לבצע debug לקוד שהוא minified - הוא פשוט לא קריא.

פיתרון אפשרי אחד הוא לזהות בצד-השרת את מצב ה-debug, ואז במקום לטעון את הקבצים ה minified - לטעון את הקבצים המלאים (שאינם minified). כל טכנולוגיה עושה זאת בצורה קצת אחרת - אך יש פה תקורה למפתחים.
דרך קצת יותר מודרנית היא להשתמש ב Source Maps - קבצים שמכילים את קוד המקור עם המיפוי לקוד ה minified כך שהדפדפן מריץ את הקוד ה Minified אך מציג לכם את קוד המקור. Source Maps יעילים גם במקרים שקוד המקור שונה מהותית מהקוד שרץ, לדוגמה כאשר כותבים ב"שפות-על" כמו LESS או CoffeeScript.
Closure Compiler, מבית גוגל, מספק יכולת לייצר source maps תוך כדי תהליך ה minification.

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



To make a long story short:
כמובן שיש ערך לדחיסה נבונה יותר של התמונות, אך גם קובצי ה javaScript שווים את המאמץ:
  • Minification של javaScript יכול עדיין להיות משמעותי בהפחתת כמות המידע להורדה. בשנים האחרונות חלקם היחסי של קובצי ה javaScript הולך וגדל משמעותית.
  • יש ייתרון בחיסכון של זמן ה CPU לדפדפן ואפשור ל Scripts לרוץ מעט יותר מוקדם. ההשפעה של קובצי ה javaScript על ה Perceived Performance היא גדולה מחלקם היחסי ב"עוגת ההורדות".
לגבי דחיסה של קובצי CSS: אכן דחיסה זו היא פחות משמעותית, וניתן להחשיב אותה כ "Nice to have".


gzip
ישנה "אלטרנטיבה זולה" לצמצום ה Bandwidh ברמת התשתיות וללא כתיבת קוד: Gzip.
ניתן להגדיר אפשרות דחיסת gzip (וריאציה של zip שקלה מאוד לפענוח) בשרת המארח כך שידחוס את הקבצים לפני שהוא שולח אותם. כל הדפדפנים כיום יודעים לקבל ולפתוח פורמט זה, וכנראה רק בשל חוסר הכרות עם הנושא - אחוז גבוה של אתרים / אפליקציות לא משתמש ביכולת ה gzip.

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

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

שרתי ווב (לדוגמה Apache) מאפשרים לציין לאילו סוגי קבצים לבצע דחיסה.
gzip הוא יעיל עבור כל פורמט טקסטואלי (כולל JSON או XML) אך אינו יעיל עבור קובצי תמונה (jpeg, png) או PDF - שהם כבר דחוסים. gzip לא יקטין אותם יותר.


טקטיקה: איחוד קבצים

נקודה #1 בשיפור ביצועי ווב היא צמצום מספר ה Roundtrips לשרת.
טכניקה יעילה למדי היא איחוד קבצים: פחות קבצים --> פחות Roundtrips.

בזמן תהליך ה build, אנו לוקחים את כל קובצי ה CSS שלנו (לעתים יש עשרות) ומאחדים אותם לקובץ אחד. מבחינת הדפדפן, חלוקה לקבצים היא שרירותית - ולכן אין שום בעיה לאחד אותם לקובץ אחד. כנ"ל לגבי קובצי javaScript.
רוב כלי ה Minification מסוגלים לבצע גם פעולה של איחוד קבצים.
באופן זה אנחנו יכולים לחסוך עשרות roundtrips לשרת ולשפר מאוד את זמן הטעינה.

ישנם 2 חסרונות גדולים לטכניקה זו:
  • אם נאחד את כל הקבצים, ייתכן ונוריד קבצים שלא נזקקים להם בתסריטים מסויימים = בזבוז ה Bandwidth.
  • הדפדפן מתחיל להריץ את קוד ה javaScript רק לאחר שביצע parsing לכולו. אם נוריד במכה אחת כמות גדולה של javaScript - ייקח זמן רב יותר עד שמשהו יחל לרוץ, מה שיפגע ב Perceived Performance. זו בעייה משמעותית באפליקציות גדולות ומורכבות.
לסיכום: טכניקה זו היא חשובה וטובה לקובצי CSS ו javaScript (וגם ל HTML Templates, אם אתם משתמשים בהן) אך יש לחשוב ולהרכיב "חבילות" בתבונה - דבר שדורש לא מעט התעסקות.



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

Sprites
Sprites הם "שדונים" ובטכניקה זו אנו מרכיבים הרבה תמונות קטנות לתוך קובץ אחד. באופן זה נוכל להוריד הרבה תמונות קטנות בעזרת Roundtrip אחד.
מקור: http://www.w3schools.com/css/css_image_sprites.asp
שפת CSS מאפשרת לנו להציג רק "צוהר" מהתמונה, באופן הבא:
  • אנו קובעים גודל נוקשה לתמונה שאנו מציגים (רוחב וגובה בפיקסלים).
  • אנו משייכים את קובץ ה sprites ל"צוהר" שהוגדר וקובעים את קורדינטות הכניסה (בדוגמה למעלה 0,0). אם היינו משנים את הקורדינטות ל 47- (x) ו 0 (y) - היינו מקבלים את החץ שמאלה.


טכניקת Sprites איננה משמשת רק לתמונות. ספריות כגון howler.js יאפשרו לכם ליצור "Audio Sprite" - קובץ אודיו אחד שמאחד הרבה קטעי קול קצרים (למשל: צליל לחיצה על כפתור או צליל החלפת דף) - ולהוריד אותם כקובץ יחיד, וכך לחסוך roundtrips.

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


Data URI
טכניקה קצת יותר חדשה ("HTML5 like") היא לבצע inlining של תמונות קטנות לתוך קובץ ה HTML/CSS עצמו. הנה דוגמה:

במקום לציין URI לתמונה ככתובת HTTP למקום בו מאוכסנת התמונה, אנו מכניסים את התמונה עצמה, מקודדת ב base64 לתוך האלמנט עצמו. ניתן לעשות זאת בתוך ה HTML עצמו (כמו בדוגמה למעלה), אך כמובן שעדיף לעשות זאת בתוך קובץ CSS.
הביטו בקוד למעלה: מזהים מה מצוייר בתמונה? תתאמצו!

זאת בדיוק הבעיה: אמנם טכניקה זו היא קצת נוחה לשימוש מ Sprites, אך היא עדיין לא-אלגנטית. חסרונות נוספים:
  • באתר בו התמונות מתחלפות בקצב מהיר - אנו מאבדים גם את היכולת לבצע caching יעיל ברמת התמונה.
  • אם אנו רוצים להוסיף אותה תמונה ב Data URI במספר קבצי CSS - העברנו את אותו המידע מספר פעמים.



שורש הבעיה

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

ובכן...הבעיה, כנראה נעוצה בפרוטוקול ה HTTP עצמו. HTTP מאפשר לבקש קבצים (resources) רק באופן סיריאלי: ביקשתי אחד, ואוכל לבקש את הבא רק לאחר שהקודם הגיע במלואו.
היה ניסיון לפתור בעיה זו ב HTTP/1.1 בעזרת מנגנון בשם Pipelining, אך מסיבות שלא אפרט כאן - המנגנון "לא סיפק את הסחורה".
ישנה תקינה לפרוטוקול HTTP/2.0 שמציעה פתרון שנראה מוצלח בהרבה, אך היא צפוייה להסתיים רק בשנת 2015, ועל כן סביר שבחמש השנים הבאות נמשיך לעשות "תרגילים" על מנת לשפר את ביצועי אפליקציות הווב שלנו.


סיכום

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


שיהיה בהצלחה!




---

[א] Cache קר אומר שלא ניגשתי לאתר זמן-מה, וה cache לא מעודכן. עם Cache "חם" (גישה לאתר בשנית לאחר 10 שניות) זמן הטעינה ירד לקצת מעל 6 שניות. לא טוב - אבל כנראה סביר.
[ב] סיפור מעניין הוא שאלגוריתם זה כשל ברשתות אלחוטיות / סללוריות בהן אחוז הכשלים ה"טבעי" הוא גבוה יחסית. היה צורך "להתאים" את האלגוריתם לרשתות אלו על מנת שיעבדו בצורה נכונה.


יום שני, 21 בינואר 2013

ביצועים של אפליקציות ווב: מבוא לצד האפל

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

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

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

פוסט זה מתארח בסדרה: אבני הבניין של האינטרנט.


פשט

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



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

הערה: כמובן שבעת שעוסקים ברמה של קישור בין מערכות, ב High Level - זו רמת הפשטה נאותה.


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




האנטומיה של קריאת HTTP

בואו ניזכר קצת בפרוטוקולי התקשורת המעורבים:
פרוטוקול HTTP הוא פרוטוקול אפליקטיבי - הוא שולח נוסח טקסט מוסכם מראש המתאר התנהגות אפליקטיבית על גבי פרוטוקול TCP.
פרוטוקול TCP - הוא פרוטוקול לניהול תקשורת (Transmission Control Protocol) שמנהל Connection לשליחת רצף של הודעות, דואג שכולן יגיעו ושיגיעו בסדר הנכון.
מי שעושה באמת את העבודה הוא פרוטוקול (IP (Internet Protocol שאחראי לשליחת הודעות, ללא הבטחת סדר וללא אמינות.

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

תרשים 1: קריאת HTTP לשרת כפי שהיא מתבצעת בפועל


DNS Lookup
כשאנחנו מקלידים כתובת (למשל http://www.ynet.co.il) יש קודם כל ללמוד מה כתובת ה IP של שרת היעד לפני שאנו יכולים לשלוח לו הודעות. כתובות אלו הן דינמיות ועשויות להשתנות לאורך הזמן. תהליך ההפיכה של הכתובת הטקסטואלית (hostname) לכתובת IP היא תהליך שנקרא DNS Lookup. בפועל הדפדפן שלנו פונה לשרת (Domain Name Servers (DNS, שהוא קורא לסדרה של שרתים אחרים, כל אחד בתורו, בכדי לפרש את הכתובת. תחילה קוראים לשרת ה ROOT כדי ללמוד על כתובת ה IP של שרת ה "il" (מפרשים את כתובת ה hostname מהסוף להתחלה). בשלב הבא עלינו לפנות לשרת "il" וללמוד ממנו את כתובת ה IP של שרת ה "co" (קיצור של commercial - הרי ynet הוא אתר מסחרי) ורק אז מקבלים את הכתובת ה IP של השרת של YNET בכבודו ובעצמו.

תהליך ה DNS Lookup לוקח בממוצע 130ms (עבור כל השרתים שבדרך). התקשורת נעשית באמצעות פרוטוקול UDP שהוא מהיר יותר מ TCP - אך איננו אמין. הסטטיסטיקה אומרת שבכ 5% מתהליכי ה DNS Lookup הודעה כלשהי הולכת לאיבוד. על הדפדפן לזהות מצב זה (ע"י קביעת timeout) ולשלוח הודעה מחדש - מה שיכול לגרום לתהליך ה DNS Lookup להתעכב זמן רב (עד כשתיים-שלוש שניות). כל זאת לפני שעוד בכלל ביצענו קריאה לשרת שלנו.


Establish TCP Connection
יצירה של TCP Connection כוללת תהליך שנקרא "לחיצת יד משולשת" שבמהלכו מתבצעות 3 קריאות של פרוטוקול IP רק כדי להסכים על ה connection. רק לאחר 3 קריאות אלו ניתן בעצם לשלוח את הודעת ה HTTP. בתקשורת מאובטחת (קרי HTTPS) יצירת ה connection מערבת "לחיצת ידיים" ארוכה בהרבה.

תיאור סכמטי של ה Three Way Handshake

HTTP Request and Response
רק לאחר שהוקם ה TCP Connection ניתן לשלוח הודעה אפליקטיבית (HTTP) לשרת. השרת מבצע את הקוד הנדרש (קורא לבסיס הנתונים או מבצע לוגיקה) ומחזיר את התשובה. זמן זה מסומן בתרשים 1 כ Server Time. יש לזכור שהשרת משקיע עבודה גם ביצירת ה TCP Connection ושליחת ההודעה עצמה - מה שמצוין בתרשים 1 כצבע הירוק ברקע.
ה HTTP Request הוא לרוב טקסט קצר למדי (כמה שורות בודדות) בעוד שהתשובה היא לרוב ארוכה למדי (קובץ HTML או קובץ JPG למשל) - ולכן אורכת זמן רב יותר.
נתון מעניין הוא ש "אינטרנט מהיר יותר" -כמעט ולא משפר גלישה רגילה באינטרנט. האינטרנט המהיר מאיץ רק את החלק של ה "HTTP Response" וכפי שניתן לראות בתרשים 1 - זהו חלק קטן מהזמן הכולל.


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


Rendering Time on the Browser
כאשר דף ה HTML מגיע לדפדפן, על הדפדפן לפענח את הפורמט (ולפעמים לתקן בו טעויות), לתרגם אותו למבנה שנקרא (DOM (Document Object Model ואז לרנדר ממנו את תצוגת הדף. תהליך דומה קורא לקבצי CSS ולקבצי javaScript. מנועי הרינדור של הדפדפנים השתפרו פלאים בשנים האחרונות - אך עדיין שלב זה גוזל זמן רב. זמני פעולה זו תלויים בחומרה של מחשב הלקוח, מנוע הרינדור של הדפדפן - וכמובן בדרך בה נכתב ה HTML / CSS / JavaScript.


Latency

התיאור שהשתמשנו בו עד עכשיו, של תקשורת IP או TCP כתקשורת של נקודה לנקודה, לקוח לשרת, איננו מדויק.
האינטרנט איננו רשת אחת, אלא מערך של רשתות שמחוברות בניהן בנתבים (Routers). מקור השם Internet הוא קיצור של inter-connected networks. בפועל כל הודעת IP מדלגת מרשת לרשת עד שהיא מגיעה לרשת של מחשב היעד - ושם היא מנותבת מקומית.
כל הודעה מנותבת באופן פרטני כך שייתכן שהודעות עוקבות ישלחו בכלל במסלולים שונים.

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

הנה הרצה של פקודת "trace route", באמצעותה אני בוחן את הדרך שהודעת IP עוברת מהמחשב האישי שלי עד לשרת עליו מאוכסן הבלוג:


כפי שאתם יכולים לראות היו 17 תחנות בדרך. התחנה הראשונה, אגב, היא הראוטר הביתי שלי (הרשת הביתית היא עוד רשת). כל תחנה בדרך מוסיפה כמה מילי-שניות ובסה"כ זמן ה Round Trip, כלומר הודעת IP הלוך וחזור, היא בסביבות ה 100ms. זהו זמן דיי טוב שמאפיין את שרתי גוגל מחוץ לארה"ב (blogger שייך לגוגל).

לאתרים ללא "נוכחות" מקומית (כמו netflix או rottentomatoes) זמן ה (Round Trip (RTT הוא כ 200-300ms בד"כ, כלומר חצי מזה לכל כיוון. בשעות העומס, המספרים גבוהים יותר.

RTT של 250ms אינו נשמע מטריד - הרי זה זמן שבן-אנוש כמעט לא יכול להבחין בו. הבעיה היא כמובן במספר ה roundrtips הנדרשים על מנת לטעון דף אינטרנט מודרני. כיום, דף אינטרנט ממוצע מורכב מ 82 קבצים ו 1MB של מידע.
בצורה הנאיבית ביותר מדובר ב 82 x יצירת TCP connections ו 82 x בקשות HTTP (כאשר HTTP הוא פרוטוקול סינכרוני ולא ניתן להוציא בקשה חדשה לפני שהתשובה מהבקשה הקודמת חזרה) = 164 המתנות של רבע שנייה (כ 40 שניות) לא כולל DNS Lookup, זמן שרת, זמן רינדור בדפדפן וללא זמן הורדת הקבצים (= Bandwidth אינסופי).

מניסיון החיים, ברור שזה לא המצב בפועל. יש הרבה אופטימזציות ברמות השונות שמשפרות את נתוני הבסיס הבעייתיים. הנה כמה אופטימיזציות חשובות:
  • פרוטוקול HTTP 1.1 הוסיף מצב של keep-alive בו ניתן לבקש לא לסגור ולעשות שימוש חוזר ב TCP connection שנוצר. השיפור: כ 100%
  • דפדפנים החלו לפתוח מספר Connections מקבילים לשרת על מנת להאיץ את הורדת הקבצים. זה החל ב 2-3 connections לשרת והיום מגיע ל 6 ואף 8 connections לשרת. השיפור: עד 800%
  • רשתות Content Delivery Networks של שרתים הפזורים ברחבי העולם מחזיקים עותקים מקומיים של שרתים ששילמו על השירות - וכך מקצרים את ה latency בצורה משמעותית. השיפור: עד 1000%. במקרי קיצון: אפילו יותר. ניתן לקרוא על CDN בפוסט תקשורת: מיהו התוכי האמיתי של האינטרנט המהיר?
  • לדפדפנים יש cache בו הם שומרים קבצים אחרונים שנטענו מקומית על המחשב וכך חוסכים את כל הסעיפים הנ"ל.  ה cache יעיל החל מהגישה השנייה לאתר. השיפור: אדיר.
ויש עוד...
עדיין - יש הרבה שאתרים / אפליקציות ווב יכולות לעשות על מנת לשפר את הביצועים שלהם ולנצל טוב יותר את התשתיות הקיימות.

ל Latency יש השפעה רבה בהרבה על ביצועי אתרי אינטרנט מאשר ה Bandwidth.
הקשר בין זמן טעינה של דף אינטרנט כתלות ב RTT


לרוע המזל, שיפור של Bandwith הוא זול יחסית (יותר כבלים) בעוד שיפור ב Latency הוא יקר הרבה יותר: כיום התעבורה למרחקים נעשית במהירות האור, ונתיבי הכבלים מוגבלים מתוואי השטח. לדוגמה: את הכבלים התת-ימיים בין ארה״ב לאוסטרליה ניתן לקצר בכ 40% באורך, וכך לשפר את ה Latency בכ 40% - אך לצורך כך יש למתוח אותם בקו ישר, מה שיגרום לעלויות אסטרונומיות. לא פלא שספקי האינטרנט מתמקדים בפרסום ה Bandwidth שלהם ולא כ"כ ב Latency (אם כי גם הוא משתפר עם השנים).


ההיבט המובילי

מכשירי מובייל, מלבד מעבד חלש יותר ו bandwidth נמוך יותר, סובלים גם מ Latency גבוה יותר. כאשר עובדים ברשת 3G, על התקשורת לעבור כמה תאים סלולריים ותחנות ממסר לפני שהם מתחברים לרשת האינטרנט מה שיכול להוסיף כ 200ms ל RTT.
כפי שאתם אמורים כבר להבין, המשמעות היא כבדה מאוד - ועל כן אפליקציות מובייל משקיעות הרבה יותר באופטימיזציות, לעתים עד האסקטרים.

הבשורה הטובה היא שרשתות דור רביעי (LTE) לא רק משפרות משמעותית את ה Bandwidth אלא גם את ה Latency - החשוב יותר. מדובר על תוספת של כ 50ms ל RTT במקום כ 200ms - שיפור גדול מאוד.


סיכום

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


שיהיה בהצלחה!



יום חמישי, 17 בינואר 2013

סקר קוראים 2013 - התוצאות


תודה לכל 101 הקוראים שנענו לבקשה וענו לסקר.

הנה התוצאות:


משמעות התוצאות:
  • האמת, התוצאות הפתיעו אותי במידה מסוימת - ועל כן אני שמח שהוא נערך. הרושם שלי היה שארכיטקטורה "תאורטית" וצד-שרת פחות מעניינים את הקוראים ודווקא צד-לקוח ומובייל הם הנושאים שבהם מתעניינים יותר (כמה פוסטים בנושאים אלו זכו להרבה מאוד כניסות).
  • תהיתי לעצמי במשך תקופה האם להעלות נושאים הקשורים לחברה בה אני עובד, SAP (חברה מעניינת, למרות התדמית המשעממת) ומערכותיה - וקיבלתי תשובה ברורה מהקוראים. @שני - אני מתנצל, אך אני כרגע שם בצד כל השקעה בכתיבה על מערכות SAP. אולי אכתוב איזה פוסט אחד להסביר "מה אני חושב שמעניין ב SAP".
  • שני נושאים שחשבתי כבר כמה זמן לכתוב עליהם הם JEE6 מול Spring/Hibernate ו node.js. אינני מתכוון לערוך סקר נוסף כדי לפלח את נושאי ה Server-Side השונים - אך אני מניח ש node מעניין אנשים הרבה יותר מ JEE ומצבה (פלטפורמה ותיקה ולא-רעה בכלל, לאחר שהוסרו ממנה כמה "גידולים סרטניים").
  • 101 קוראים שגם משתתפים (ב 4 ימים) - הוא pulse check חשוב מבחינתי עבור הבלוג. תודה!
  • כפי שציינתי קודם לכן, הסקר הוא אינפוט חשוב עבורי - אבל אני צופה שההשפעה שלו על תוכני הבלוג תהיה מידתית.
  • בכל מחשבה, רעיון או הערה, אתם תמיד מוזמנים להגיב (גם בלי קשר ל"סקר") או לחלופין לכתוב לי ישירות ל baronliorATgmail.com (אני נמנע לכתוב @ וכותב AT כדי לחמוק מ crawlers של כתובות מייל....)

ליאור

---------------


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

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

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

אם יש לכם נושאים מעניינים אחרים - פשוט הוסיפו תגובה לפוסט.


תודה ושנה טובה,
ליאור


יום שלישי, 8 בינואר 2013

סימני המהפכה (מובייל)

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

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


שינוי? אתם בטוחים?

הנה אחד הגרפים שעבורי הוא עוצמתי במיוחד:

במהלך שנות ה-80, Wintel (צימוד של Windows ו Intel) השתלטו לחלוטין על שוק המיחשוב - על חשבון כמעט כל השחקנים האחרים. הם שלטו בעוצמה במהלך שנות ה-90 ושנות ה-2000, כמעט 2 עשורים. לפתע פתאום, בשנים ספורות, המערכות שהם מייצרים ומוכרים הפכו להיות מיעוט של המערכות הנמכרות. בשנת 2012 רק כשליש ממערכות המחשוב האישי שנמכרו היו WinTel.
הנתונים בגרף הם דיי מדהימים וכנראה לא מבטאים את התחושה שיש לרבים מאיתנו: ה PC עדיין כאן, ומקומו יציב.

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

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

במקום Windows יש את Android ו iOS.
במקום מעבדי Intel ישנם מעבדי ARM.

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

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


על אופניים ומשאיות

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

כיצד ניתן להסביר זאת?
חשבו לדוגמה על אופניים. אנשים רבים קונים ומשתמשים בהם. אופניים "רגילים" עולים 500, אולי 1000 ש"ח. נאמר שמחר מופיעה חברה בשם "אגס" ומציעה אופניים מ-ד-ה-מ-י-ם במחיר 100,000 ש"ח. כמה זוגות אופניים אתם חושבים שימכרו? בוודאי יש כמה טייקונים ובני עשירים שלא יתקשו להוציא סכום שכזה - אך הם עדיין מעטים.
מנכ"ל "אגס", סתיו עובד, מסביר בתוקף שזו קטגוריה שונה של מוצר: באופניים שלו יכולה ליסוע ביחד משפחה שלמה. החוויה נעימה ונוחה הרבה יותר, שקטה ונעימה. לא נכון להשוות אותם ל"אופניים סתם".
אבל, 100,000 ש"ח? השתכנעתם?

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

מהצד השני יש את המחשב האישי: ה PC. ה PC, כפי שתיאר אותו פעם סטיב ג'ובס (לא לבלבל עם סתיו עובד), הוא כמו משאית: הוא כלי עבודה מקצועי, מאוד Capable - שאינו מותאם לצורכיהם של רוב המשתמשים. ה PC גדול, מסורבל, מסובך לשימוש ואיני אופטימלי לסט המשימות שאנו נוהגים לעשות הכי הרבה: לקרוא מייל או מסמך, לשמוע מוסיקה או לראות סרטון ביו-טיוב.
כמו משאיות, ה PC לא צפוי להיעלם - זהו כלי עבודה חשוב. ייתכן והוא יהפוך להיות נישה קטנה, שכוללת אולי 5% מהמחשבים בעולם. כפי שיש הרבה משאיות וכמה חברות מרוויחות מייצורן יפה, אך הן עדיין המיעוט.


עד כמה ההצלחה של אפל היא גדולה?

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

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

אפשר לומר שאפל היא חברת חומרה, כיצד אם כן היא משתווה לייצרני ה PC הגדולים? ובכן: אפל מרוויחה כפול מיבמ, לנובו, HP, אינטל, דל, אייסר ואסוס ביחד.

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

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

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


שיהיה בהצלחה בעולם החדש!