Website Icon

השוואה בין Server ל-Client קומפוננטות ב-Next.js

תמונה המציגה לוגו של Next.js למעלה, עם  Server Component ו-Client Component מתחתיו משני צדי קו, והכיתוב VS. בתחתית.

הקדמה

היכולת לבחור היכן לבצע רינדור של הקומפוננטות, יכולה לשפר משמעותית את ביצועי האפליקציה. Next.js מציעה אפשרות לבחור אם לבצע רינדור קומפוננטות בשרת או בצד הלקוח בהתאם לצורך. במאמר זה נסביר מה הם Server Components ו-Client Components, נבחן את היתרונות והחסרונות של כל גישה, ונבין מתי כדאי להשתמש בכל אחת מהן.

לפני שאתם קוראים את המאמר הזה, רצוי שיהיה לכם ידע בסיסי על סוגי רינדור שונים כמו Client-side rendering (CSR) ו-Server-side rendering (SSR).

מה זה Server Components

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

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

מה זה Client Components

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

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

מתי להשתמש ב-Server Components לעומת Client Components

ב-Next.js, הקומפוננטות מוגדרות כברירת מחדל כ-Server Components, אלא אם כן ציינתם אחרת על ידי 'use client'. השתמשו ב-Server Components כברירת מחדל והחליפו ל-Client Components כשנדרש. הנה סיכום מתי להשתמש בכל אחת מהן:

היתרונות של Server Components

שאיבת נתונים (Data Fetching)

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

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

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

אבטחה (Security)

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

הקטנת תלות ב-JavaScript בצד הלקוח

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

מטמון (Cache)

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

סטרימינג (Streaming)

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

תרשים המציג הקבלה של קטעי נתיבים בסטרימינג, כולל שאיבת נתונים, רינדור והידרציה.
By Next.js Documentation

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

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

היתרונות של Client Components

אינטראקטיביות (Interactivity)

קומפוננטות צד לקוח יכולות להשתמש ב-state, כמו useState לדוגמה, ב-effects כמו useEffect, ו-event listeners כמו onClick. זה מאפשר להן לספק משוב מיידי למשתמש ולעדכן את ממשק המשתמש בזמן אמת. לדוגמה, כפתורים שמשנים צבע כאשר המשתמש לוחץ עליהם, או טפסים שמגיבים מיידית להזנת הנתונים.

גישה ל-API של הדפדפן

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

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

רוצים לקרוא עוד על הנושא "מתי להשתמש ב-Server Components לעומת Client Components" היכנסו לדוקומנטציה של Next.js.

שילוב קומפוננטות צד שרת וצד לקוח ב-Next.js

ב-Next.js, הקומפוננטות מוגדרות כברירת מחדל כ-Server Components, אלא אם ציינתם אחרת באמצעות 'use client'. השתמשו ב-Server Components כברירת מחדל והחליפו ל-Client Components כשנדרש. ניתן גם להשתמש ב-'use server' כדי להגדיר קוד שרץ בשרת בלבד, גם בתוך קומפוננטת לקוח.

  • אם יש לי Client Component בתוך Server Component, כל הקוד של Server Component ירוץ על השרת, למעט Client Component שתתרנדר בצד הלקוח.
  • לעומת זאת, אם יש לי Client Component ובתוכה Server Component, קומפוננטת צד השרת תיחשב כ-Client Component ולכן תרוץ בצד הלקוח גם אם אין הנחיית 'use client' על ה-Server Component.

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

בתמונה למטה, תוכלו לראות דוגמה של דף שבו חלק מהקומפוננטות מתרנדרות בצד השרת ולכן הן Server Components, וחלק מהקומפוננטות מתרנדרות בצד הלקוח ולכן הן Client Components. האפשרות שלנו להחליט מה ייתרנדר בצד השרת ומה בצד הלקוח מורידה עומס מהדפדפן ומאיצה את טעינת האתר.

ממשק משתמש המחולק לקומפוננטות צד לקוח (סגול) וקומפוננטות צד שרת (כחול).
By Next.js Documentation

סיכום

Next.js מאפשרת לנו לחשוב מחדש על הדרך בה אנו מרנדרים את האפליקציות שלנו ולהתאים את תהליך הרינדור בהתאם לצרכים של כל רכיב. Server Components מאפשרים לנו להקטין את עומס הקוד בצד הלקוח ולשמור על מידע רגיש בשרת, בעוד Client Components מאפשרים לנו להוסיף אינטראקטיביות ואינטגרציה עם הדפדפן. שילוב נכון בין שתי הגישות יכול לשפר את ביצועי האפליקציה ולהעניק חוויית משתמש טובה יותר.