הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

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

17/12/2024

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

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

import { useState, useLayoutEffect, memo, useEffect } from 'react'
import './App.css'

const Text = function Text() {
  return <p>Hello World</p>
}

function App() {
  return (
    <div>
      {new Array(10000).fill(0).map((_, i) => <Text key={i} />)}
    </div>
  )
}

export default App

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

  1. תוספת useEffect ריק בתוך הקומפוננטה מעלה בערך פי 1.5 את זמן ביצוע הסקריפט.

  2. ירידה מ 10,000 קומפוננטות טקסט ל 1,000 קומפוננטות טקסט מתורגמת לזמן ריצת סקריפט פי 5 יותר מהיר.

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

  4. הוספת memo לקומפוננטה מאטה קצת את זמן הריצה.

  5. הוספת state לקומפוננטה כמעט ולא משפיעה על זמן הריצה.

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

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

  2. קומפוננטות דורשות משמעותית יותר משאבים מ DOM Elements. לפעמים שווה לאחד כמה קומפוננטות כדי לשפר ביצועים (בהנחה ששתיהן מושפעות מאותו State).

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

כש Best Practices משתנים

16/12/2024

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

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

  1. מה הפקודה הזאת שראיתי במדריך ואני לא מכיר?

  2. למה היו צריכים אותה?

  3. למה שינו את זה? למה היום כבר לא משתמשים בשיטה הזאת?

  4. (במיוחד עבור שיטות שעדיין עובדות) באיזה מקרים ה Best Practice החדש טוב יותר מהישן? האם יש עדיין סיבות להשתמש בשיטה הישנה?

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

צריך לאהוב

15/12/2024

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

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

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

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

הנה כמה דרכים לחשוב על זה, גם כשאנחנו בתחילת הדרך:

  1. אני אוהב לתכנת, אפילו שזה קשה ואני עדיין לא טוב בזה.

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

  3. מעניין מה יקרה אם אכתוב את זה...

  4. מעניין באיזה שפת תכנות השתמשו בשביל לבנות את הכלי הזה...

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

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

שלוש סיבות שגורמות לנו לבנות ארכיטקטורה לא נכונה

14/12/2024

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

המשך קריאה

טיפ פייתון: הרצה משורת הפקודה עם uv

13/12/2024

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

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

import pandas

mydataset = {
          'cars': ["BMW", "Volvo", "Ford"],
            'passings': [3, 7, 2]
            }

myvar = pandas.DataFrame(mydataset)

print(myvar)

אז הכי הייתי רוצה ש uv יבין לבד משורת ה import שצריך להתקין את pandas, אבל זה עדיין לא קורה. מה שכן אני יכול לעדכן את הקוד ולהוסיף לו כותרת מיוחדת עבור uv באופן הבא:

#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "pandas",
# ]
# ///

import pandas

mydataset = {
          'cars': ["BMW", "Volvo", "Ford"],
            'passings': [3, 7, 2]
            }

myvar = pandas.DataFrame(mydataset)

print(myvar)

ועכשיו אפשר להפעיל את הקסם:

ynonp@Ynons-MacBook-Air ~/tmp $ uv run pandas-demo-uv.py

Reading inline script metadata from `pandas-demo-uv.py`
Installed 6 packages in 38ms
    cars  passings
0    BMW         3
1  Volvo         7
2   Ford         2

באופן אוטומטי uv יצר סביבה וירטואלית בשביל הסקריפט, התקין לתוכה את pandas ולא זיהם לי את ספריית ההתקנה הכללית של פייתון.

את uv אני התקנתי עם homebrew:

$ brew install uv

אבל אפשר גם להתקין אותו עם pip:

pip install uv

ויש לו גם דף תיעוד מרשים בכתובת:

https://docs.astral.sh/uv/

שיפור זמני טעינת עמוד ב 2025

11/12/2024

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

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

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

  3. הגודל כן קובע - פעם המלצנו לאנשים לחבר יחד כמה שיותר קבצי JS או CSS לקובץ אחד כי היתה מגבלה על כמה קבצים דפדפן יכול להוריד במקביל וכל הורדה של קובץ נוסף דרשה Round Trip לשרת למשוך את הקובץ. כל זה לא רלוונטי יותר בזכות התפתחות בפרוטוקולי התקשורת. מצד שני דפדפנים לא התפתחו באותה מהירות כמו הרשת ולכן קובץ JS גדול יכול להשפיע לרעה בצורה מאוד משמעותית על זמן טעינת העמוד. בטאב Performance בדפדפן אפשר לראות את כל הקבצים שהעמוד טוען ובאיזו מידה כל קובץ משפיע על העבודה ב Main Thread. שימו לב למספרים האלה ושברו קבצי JS גדולים.

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

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

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

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

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

  9. טענו מראש (preload) את קבצי הפונטים, תמונות רקע וכל משאב אחר שה CSS שלכם עוד מעט יבקש כבר ב HTML.

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

טיפ פייתון: איך לשלוח סקריפט בלי להראות את הקוד

10/12/2024

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

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

בשביל לקמפל סקריפט בשם demo.py אני מפעיל:

python -m compileall demo.py

זה יוצר תיקייה בשם __pycache__ ובתוכה קובץ בשם demo.cpython-313.pyc. בשביל להריץ צריך להפעיל:

python __pycache__/demo.cpython-313.pyc

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

חמישה טיפים להמשך לימוד Vue

09/12/2024

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

המשך קריאה