Archive for the Category »תכנות «

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

אבל הפוסט הזה הוא לא דווקא על jQuery ושאר הספריות הפומביות הנמצאות שם – אלא דווקא על הדרך בה כדאי להשתמש בה באתר שלכם: CDN.

CDN הם ראשי התיבות לContent Delivery Network, ובגדול, שימוש בurl אחד המפוזר בסרברים שונים ברחבי העולם. השילוב הזה של כתובת אחת וסרברים מפוזרים חשוב ביותר נותן לכם שלושה דברים עיקריים בבת אחת (שימוש בזכרון מטמון, מהירות גישה וכפילות גישה) – וללא עלות כלל. במקרה של jQuery המאוחסנת בCDN של גוגל (יחד עם עוד ספריות) – היתרונות אפילו גדולים יותר מאשר רשת CDN פרטית שלכם.

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

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

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

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

במקום זה אני מציע פשוט להכניס את הספרייה ישירות לדף הhtml שלכם:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>

עוד שני טיפים קטנים ששווה לחשוב עליהם:

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

גירסה אחרונה – בכתובת הנ"ל אתם משתמשים בגירסה הרצויה של jQuery. אם תרצו להשתמש בגירסה האחרונה, השתמשו בסיפרה "1" ללא נקודה.

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

שימוש במנגנון מטמון cache:

שימוש המודולים למטמון ()cache, כמו Memcache, או שפת תבניות שתומכת במטמון (כמו Smarty) יכולה לשפר את הביצועים של האתר בקלות.

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

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

לא להעתיק משתנים ללא סיבה:

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

דוגמא רעה:

$description = $_POST['description'];
echo $description;

דוגמא טובה:

echo $_POST['description'];

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

שימוש במנגנון הבאפר של PHP:

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

המנעו מכתיבת שאילתות SQL בלולאה:

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

$userData = [];
foreach ($userList as $user) {
$userData[] = '("' . $user['first_name'] . '", "' . $user['last_name'] . '")';
}
$query = 'INSERT INTO users (first_name,last_name) VALUES' . implode(',', $iserData);
mysql_query($query);
Produces:
INSERT INTO users (first_name,last_name) VALUES("John", "Doe"),("Jane", "Doe")...

שימוש בגרש אחד עד כמה שאפשר במקום גרשיים:

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

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

במקום:

echo 'hello, my name is '. $myName .', how are you?';

עדיף:

echo 'hello, my name is ', $myName, ', how are you?';

להשתמש בSWITCH במקום בIF.ELSE

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

גוגל יצאו עם תוסף נהדר למפתחי אתרים – הGoogle Page Speed, תוסף שמתלבש על Firebug הנהדר ומביא פונקצנליות די דומה לזו של YSLOW – הצעות ושיפורים לביצועים באתר – אבל בצורה הרבה יותר טובה.

התוסף מוסיף שני טאבים לFIREBUG – טאב ראשון הוא לשיפורי ביצועים – ולאחר לחיצה עליו הוא מנתח את כל הקיראות לאתר שלכם. התוצאות מנותחות ומוצגות – משיפורי מבנה, בצורה די דומה לזו של YSLOW רק קצת יותר ברורה (השינויים מוצגים בתוסף ולא מופנים לאתר של YAHOO), עד שיפורי כיווץ תמונות וJS, כולל כיווץ התמונות בשבילכם (!) כך שכל מה שצריך לעשות זה ללחוץ, להעתיק את התמונה ולשבץ אותה במקום התמונה הישנה.

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

התוסף או בקוד פתוח. מומלץ.

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

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

  • השאילתה היתה מורכבת משאילתה ותת שאילתה. תת השאילתה החזירה בנתונים הנוכחיים בין 0 ל200-300 תוצאות, ששאילתת האב לקחה מתוכן מידע. האופציה הראשונה אם כך, היתה לפרק את תת השאילתה לבקשה בזכות עצמה, לעבד את הנתונים, ולשלוח לשאילתה הראשונה. היתרונות: עיובד הנתונים אפשר עוד אופטימיזציה לוגית, וקריאות נפרדות לmysql איפשרו פחות זמן של נעילה של טבלאות. החסרונות: שתי קריאות לתוך הדאטהבייס עולות יותר זמן, והשיפור הסופי אינו גדול כל כך, בסה"כ, רק מפוצל.
  • הקמת memcache או שירות דומה (שכבר קיים במערכת) לשמירה של תוצאות מגבול מסויים, או פופלריות במיוחד, עם או בלי השיפור בנקודה הקודמת, ושימוש בהם ישירות מהזיכרון, ועדיין לסבול במידה זו או אחרת משאר השאילתות. היתרון: מהירות בשאילתות חביבות אשר נקראות יותר מהרגיל. החסרון: שימוש רב בזכרון יקר, לא ברור בכלל אם יש מבין השאילותות כאלה שנקראות פעמים רבות הרבה יותר מאחרות, וגם אם כן – הכמות של השאר שנקראות פעם או פעמיים כל אחת כל כך גדולה, שבסה"כ העומס על המערכת לא יורד.
  • שמירה של התוצאות, אפילו שמירה של הhtml שנוצר, בקובץ על הדיסק, אשר נמחק ברגעים חשובים או בטריגרים מסויימים, ובזמן אמת פשוט נקרא מהדיסק ללא פניה לדאטהבייס. היתרונות: מהיר, ללא שימוש בזיכרון, שיפור קריאות מוחלט לmysql. החיסרון: מקום על הדיסק, סיבוך במחיקה נכונה של המידע השמור, זמן גישה ארוך יחסית לדיסק.

מה אתם הייתם בוחרים? האם יש אפשרויות נוספות?

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

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

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

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

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

10 דקות אחרי זה, בדף המשימות כבר חיכו לי 12 משימות קטנות לפני העלייה לאויר.