העתקת טקסט ותמונות ל Clipboard מתוך JavaScript
הממשק navigator.clipboard מאפשר לנו להעתיק דברים ל Clipboard באפליקציית ווב מתוך קוד JavaScript והאמת שהעבודה איתו הפתיעה אותי לטובה. הנה שתי דוגמאות וכמה טיפים על דברים שיכולים להסתבך.
טיפים קצרים וחדשות למתכנתים
הממשק navigator.clipboard מאפשר לנו להעתיק דברים ל Clipboard באפליקציית ווב מתוך קוד JavaScript והאמת שהעבודה איתו הפתיעה אותי לטובה. הנה שתי דוגמאות וכמה טיפים על דברים שיכולים להסתבך.
העולם משתנה כל הזמן וגם אצלנו בווב יש חידושים ובמיוחד בכל מה שקשור לארכיטקטורה של מערכות וההשפעה של אותה ארכיטקטורה על זמני טעינת העמוד. ממש בכניסה ל 2025 אני רוצה לחדד כמה רעיונות ישנים שעדיין עובדים ולזרוק את אלה שכבר לא רלוונטיים. אלה 10 טיפים שהייתי מאמץ גם לשנה הבאה בשביל לבנות אתרים שנטענים מהר:
פחות זה יותר - קובץ HTML קטן שנטען מ CDN יעלה הכי מהר אצל הלקוחות. חישבו טוב כל פעם שמכניסים פיצ'ר למערכת איך הוא משפיע על זמני טעינת העמוד והאם ניתן לבנות מנגנון דומה עם פחות קוד.
הקפידו לבקש את ה Cache - ההורדה הכי מהירה היא הורדה שלא קורית כי הקובץ כבר אצל הלקוח. שימו לב שאתם מגדירים Cache לכמה שיותר קבצים בעמוד. הקפידו לארגן את ה Assets של הדף שלכם כך שאפשר יהיה לשמור כמה שיותר ממנו ב Cache, כלומר השתמשו בשמות קבצים עם מזהים שאפשר לשמור ב Cache וחלקו את הקבצים כך ששינוי בקובץ אחד ישפיע רק על מעט קוד.
הגודל כן קובע - פעם המלצנו לאנשים לחבר יחד כמה שיותר קבצי JS או CSS לקובץ אחד כי היתה מגבלה על כמה קבצים דפדפן יכול להוריד במקביל וכל הורדה של קובץ נוסף דרשה Round Trip לשרת למשוך את הקובץ. כל זה לא רלוונטי יותר בזכות התפתחות בפרוטוקולי התקשורת. מצד שני דפדפנים לא התפתחו באותה מהירות כמו הרשת ולכן קובץ JS גדול יכול להשפיע לרעה בצורה מאוד משמעותית על זמן טעינת העמוד. בטאב Performance בדפדפן אפשר לראות את כל הקבצים שהעמוד טוען ובאיזו מידה כל קובץ משפיע על העבודה ב Main Thread. שימו לב למספרים האלה ושברו קבצי JS גדולים.
אבל לא תמיד - שימו לב שגם קבצים קטנים יכולים להשפיע על זמן העבודה של ה Main Thread, לפעמים אפילו יותר מקבצים גדולים. כן יש JavaScript שלדפדפן יותר קשה להריץ. אם ראיתם כאלה קבצים שברו גם אותם, ואם אלה קבצים של ספריית צד שלישי אל תתביישו לחפש ספרייה אחרת.
זמן התגובה של השרת היה ונשאר פקטור בסיסי בשיפור ביצועים. ה HTML צריך להישלח חזרה תוך פחות מחצי שניה, עדיף לכיוון ה 200 מילי.
לא צריך לעשות היום מה שאפשר לדחות למחר - נשלח לגולש רק את הקוד שהוא צריך, ורק את הגדרות העיצוב שהוא צריך. אם מישהו ניסה להגיע לדף "אודות" באתר הוא לא צריך לחכות שדף הבית ייטען. קודם תנו לבן אדם את מה שהוא רצה, אחרי זה תשתמשו ב preload כדי לטעון דפים אחרים ברקע אם לדעתכם יש בזה צורך.
ספריות צד שלישי יכולות להכביד. עדיף לבנות לבד אתר נגיש מאשר להטמיע תוסף נגישות. אם אתם לא מסתכלים ב Analytics לא צריך להוסיף את הסקריפט שלהם לעמוד.
תמונות ריספונסיביות זה עדיין רעיון טוב. אין טעם לשלוח תמונה גדולה ולהקטין אותה ב CSS.
טענו מראש (preload) את קבצי הפונטים, תמונות רקע וכל משאב אחר שה CSS שלכם עוד מעט יבקש כבר ב HTML.
הקשיבו למשתמשים - רוב שירותי האנליטיקס מאפשרים לשמור כמה זמן לקח למשתמשים אמיתיים לטעון את העמוד שלכם. זה המדד הכי טוב כדי להבין אם יש או אין בעיות ביצועים. היו ערניים לשינויים במדד זה והקפידו לצעוק כששינויי קוד מסוימים גורמים למשתמשים לחוות האטה בזמני הטעינה.
חבר שואל - איך אני שולח סקריפט פייתון למשתמשים בלי שיוכלו לראות את הקוד? מסתבר שיש פיתרון פשוט ומובנה בפייתון: קומפילציה.
במקום לתת את הסקריפט תוכלו לבקש מפייתון לקמפל אותו ותקבלו קובץ pyc. נותנים ללקוח את קובץ ה pyc ורובם לא ידעו איך לקרוא אותו.
בשביל לקמפל סקריפט בשם demo.py
אני מפעיל:
python -m compileall demo.py
זה יוצר תיקייה בשם __pycache__
ובתוכה קובץ בשם demo.cpython-313.pyc
. בשביל להריץ צריך להפעיל:
python __pycache__/demo.cpython-313.pyc
נ.ב. שימו לב שהפיתרון הזה לא רלוונטי כדי להגן על הסקריפט שלכם מתוקפים מתוחכמים או אפילו אנשים טכניים שקצת מוכנים להתאמץ. יש כלים פשוטים שיודעים לעשות decomlile לקוד פייתון, ואפילו מהקוד המקומפל אפשר ללמוד הרבה דברים. ובכל זאת הרבה פעמים פיתרון פשוט זה בדיוק מה שאנחנו צריכים במיוחד להפצה של סקריפטים בתוך הארגון כשאנחנו לא רוצים שמי שמקבל את הסקריפט יתחיל לעשות שינויים ואז יבוא בטעות שדברים לא עובדים.
כל הכבוד! הצלחתם לכתוב כמה דוגמאות ב Vue ואתם מרגישים שאתם מוכנים לדבר האמיתי. לפני שתצללו לכתיבת המערכת הגדולה הראשונה שלכם אני רוצה לשתף בפוסט זה 5 טיפים שיעזרו לכם להתקדם ב Vue גם אחרי שלב הלימוד:
ריאקט 19 שוחרר ממש לפני כמה ימים והפיצ'ר הכי מרגש שהוא מביא לשולחן הוא התמיכה בקומפוננטות אסינכרוניות. בפוסט זה נראה איך זה עובד ולמה חשוב לשים לב.
אחד הטרנדים של ריילס היום הוא לוותר על ה Build Step ולהשתמש רק ב JavaScript. בניסוי היום כתבתי פרויקט ריילס שמשלב את vue כדי לראות איך זה עובד ובמה זה שונה מפרויקט צד-לקוח רגיל.
שתי מילים מאוד דומות בעברית עם משמעות שלפעמים נראית הפוכה. אנשים "פרודוקטיביים" מייצרים דברים וגורמים לחברה לפעול. אנשים "קריאייטיביים" ממציאים רעיונות חדשים, סיפורים, אומנות, שירים. בטח שכדאי להיות יצירתי אבל זה הפרודוקטיבי שמשלם את החשבון. או לפחות ככה חשבנו.
בעולם של היום אלה שתי מילים שהולכות יחד יד ביד. אנחנו לא צריכים עוד מכוניות, עוד טלוויזיות או עוד נייר טואלט, אפילו אם תצליחו לייצר אותו קצת יותר יעיל או קצת יותר זול. הפרודוקטיביות היום היא קודם כל היכולת לראות מה אנשים צריכים ולהמציא פיתרונות לבעיות שאחרים עוד לא ראו. קריאייטיביות היא הבסיס לפרודוקטיביות.
הקוד הזה עובד, אבל גורם לטייפסקריפט לכעוס:
<script setup lang="ts">
import { inject } from 'vue';
import { translations } from './InjectionKeys';
const texts = inject(translations);
</script>
<template>
<button>{{ texts['click-here'] }}</button>
</template>
הקומפוננטה לוקחת מהקונטקסט את הערך הכי קרוב של המשתנה translations ואז מושכת ממנו את התרגום של הטקסט click-here
. אין שגיאות בקונסול ועל המסך הכל נראה תקין. יותר מזה, אם בטעות מישהו שכח לעשות provide ל texts מיד נראה את השגיאה בקונסול כי ננסה לקרוא מפתח מתוך null. אני בסדר עם ההתנהגות הזאת כי אין לי מה לעשות עם המערכת אם אפילו הטקסטים לא נטענו. הבעיה שטייפסקריפט לא יודע את כל מה שאני יודע ומסמן את שורת הכפתור ב template באדום. מה עושים? שתי הצעות-
דרך אחת היא להוסיף בדיקה בקוד הסקריפט אחרי inject:
<script setup lang="ts">
import { inject, ref } from 'vue';
import { translations } from './InjectionKeys';
const texts = inject(translations);
if (!texts) {
throw new Error("Missing texts in parent component");
}
</script>
<template>
<button>{{ texts['click-here'] }}</button>
</template>
קיבלנו הודעת שגיאה קצת יותר טובה וטייפסקריפט רגוע. דרך שניה היא להעביר פרמטר שני ל inject שהוא ערך ברירת המחדל:
<script setup lang="ts">
import { inject, ref } from 'vue';
import { translations } from './InjectionKeys';
const texts = inject(translations, ref<Record<string, string>>({}));
</script>
<template>
<button>{{ texts['click-here'] }}</button>
</template>
פה הקוד יותר קצר שזה נחמד, אבל החיסרון הוא שעכשיו אם מישהו שוכח להעביר את texts מקומפוננטה עליונה יותר לא נראה שגיאה בקונסול אלא רק טקסטים ריקים. כנראה שגם זה לא נורא כי זאת שגיאה שמאוד קל לזהות.
איזה משתי הגישות אתם מעדיפים? או שאולי יש לכם טכניקה אחרת? מוזמנים לספר בתגובות או בטלגרם.
הפוסט כאן נוגע בנקודה טובה לגבי SQL: https://www.depesz.com/2024/12/01/sql-best-practices-dont-compare-count-with-0/
בקצרה הוא מסביר למה לא כדאי לכתוב את זה:
SELECT u.* FROM users u
WHERE 0 = (SELECT COUNT(*) FROM addresses a WHERE a.user_id = u.id);
כשבעצם היה צריך לכתוב את זה:
SELECT u.* FROM users u
WHERE NOT EXISTS (SELECT FROM addresses a WHERE a.user_id = u.id);
אבל אני חושב שהנקודה פה יותר גדולה מ SQL ויותר גדולה מבעיית ביצועים אחת פחות:
קוד רע משתכפל - כשאני בודק אם count של משהו שווה 0, גם אם במקרה הספציפי שלי זה לא שבר את המערכת, מישהו אחר יעתיק את זה במקום אחר ושם אולי זה יישבר. מבט קדימה על עולם בו AI יכתוב קוד, תבניות רעות בקוד שלנו הולכות להשתכפל הרבה יותר.
קוד רע הוא מורה רע - מתכנתים צעירים שיעבדו על מערכת עם הרגלים רעים יאמצו את אותם הרגלים רעים ואפילו לא ידעו שקיימת דרך יותר טובה. וככה אנחנו מקבלים מפתחים עם 5 שנים ניסיון ב SQL שעדיין יהיו מופתעים לגלות שיש דבר כזה EXISTS, כי הם אף פעם לא ראו אותו בקוד שלהם.
ופה החשיבות של היכרות טובה עם השפה: ככל שאני מכיר טוב יותר את כל הפקודות בשפה קל לי יותר למצוא את הפקודה שפותרת לי את הבעיה בצורה מדויקת, יעילה ומעבירה את המסר הנכון לאלה שיקראו את הקוד.
לימוד יחד עם חברים יכול להיות הרבה יותר אפקטיבי מלימוד לבד: המחויבות החברתית מגבירה את המוטיבציה, חברים יכולים לעזור כשאנחנו נתקעים ולהעלות שאלות שלא חשבנו עליהן.
עכשיו עם ה AI אפילו לא צריך מורה שילווה אותנו. בהינתן נושא, חומרי לימוד ורשימת משימות מתכנתים בעלי מוטיבציה יכולים להגיע מאוד רחוק. והנה רעיון לפרויקט צד נחמד ולא קשה מדי, מערכת להקמה ותפעול קבוצות לימוד. בגדול:
משתמשים יכולים להיכנס ולהקים מסלולי לימוד. מסלולי הלימוד יוכלו להיות בתשלום או בחינם, והם כוללים סילבוס מסודר, משימות ואולי פיתרונות עם הסברים.
משתמשים אחרים יכולים להיכנס ולהקים קבוצות לימוד. כשאני מקים קבוצת לימוד אני בוחר את השעות והימים בהם מסתדר לי ללמוד, מספר על עצמי ומה הרמה שלי ועם איזה סוג מפתחים הייתי רוצה ללמוד. בהקמת קבוצת לימוד אני גם בוחר את מסלול הלימוד של הקבוצה.
משתמשים אחרים יכולים להיכנס, לחפש קבוצות לימוד ולהצטרף.
אני חושב שהמשחק של קבוצות לימוד יוצא מהתבנית של אתרי קורסים ומשנה את הפוקוס, במקום לבחור קורס לפי ביקורות או סילבוס, אני בוחר לפי האנשים איתם אני רוצה ללמוד. הרבה פעמים התוצאה תהיה לימוד יותר אפקטיבי.
חושבים לבנות את הפרויקט ורוצים להתייעץ על טכנולוגיה או ארכיטקטורה? אל תתביישו להשאיר הודעה. בניתם אותו או משהו דומה? ספרו לי על זה ואשמח להשתמש ולעזור לכם לקדם.