- Server Components הן ברירת המחדל ב-Next.js App Router; מתרנדרות בשרת, לא נשלחות ללקוח כ-JavaScript, ומתאימות לתוכן סטטי, שאיבת נתונים מאובטחת וביצועים טובים.
- Client Components מסומנות עם 'use client' בראש הקובץ; רצות בדפדפן ותומכות ב-state, effects, event handlers וב-API של הדפדפן.
- כלל אצבע להתחיל תמיד עם Server Component, ולעבור ל-Client Component רק כשנדרשת אינטראקטיביות (כמו onClick, useState או localStorage).
- אופטימיזציה חשובה לדחוף את ה-Client Components עמוק בעץ הקומפוננטות - לעטוף עלים אינטראקטיביים בלבד - כדי להקטין את ה-bundle בלקוח.
ההבדלים בין Server Components ל-Client Components
ב-Next.js App Router (זמין מאז Next.js 13, אוקטובר 2022), Server Components הן ברירת המחדל - הן מתרנדרות בשרת ולא נשלחות ללקוח כ-JavaScript. Client Components מסומנות באמצעות הוראת 'use client' בראש הקובץ, רצות בדפדפן, ותומכות ב-state, effects, event handlers ו-APIs של הדפדפן (localStorage, geolocation, וכן הלאה).
הכלל המעשי שצוות Next.js ממליץ עליו: התחילו תמיד עם Server Component, והמירו ל-Client Component רק במקום שבו נדרשת אינטראקטיביות אמיתית - כפתור עם onClick, טופס עם useState, או גישה ל-API של הדפדפן. כך ה-JavaScript bundle שנשלח ללקוח נשאר מינימלי, וזמן הטעינה של הדף משתפר משמעותית.
מה זה Server Components
קומפוננטות צד שרת הן קומפוננטות שמתרנדרות בשרת בזמן בניית האפליקציה (Build Time) או כאשר המשתמש מבצע בקשות (Request Time). שיטה זו מתאימה במיוחד לקומפוננטות שאינן אינטראקטיביות, כמו כותרות, טקסטים ותמונות.
כאשר קומפוננטה מתרנדרת בשרת, היא נשלחת לצד לקוח כשהיא כבר מוטענת ומוכנה להיות מוצגת, ללא צורך בעבודה נוספת מצד הדפדפן. Server Components ידועות גם כ-RSC (React Server Components).
מה זה Client Components
קומפוננטות צד לקוח הן קומפוננטות שנטענות ומתרנדרות בצד הלקוח (בדפדפן) ומשמשות לאינטראקציה עם המשתמשים. דוגמאות לקומפוננטות צד לקוח כוללות כפתורים, טפסים, שדות חיפוש וכל אלמנט אחר שהמשתמש יכול לבצע בו אינטראקציה.
קומפוננטות אלו חייבות להיטען ולהתבצע בצד הלקוח מכיוון שהדפדפן תומך באלמנטים אלו וב-Events כמו 'onClick', מה שמאפשר להוסיף אינטראקטיביות. בצד השרת אין תמיכה באירועים אלו מכיוון שהסביבה שונה ואין צורך באירועים כמו 'onClick' בשרת.
מתי להשתמש ב-Server או 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)
קומפוננטות צד שרת מאפשרות לפצל את תהליך הרינדור לחלקים, אשר מוזרמים ללקוח ברגע שהם מוכנים. גישה זו מאפשרת למשתמשים להתחיל לראות חלקים מהדף עוד לפני שהרינדור של כל הדף הושלם בשרת. בכך היא מפחיתה את זמן ההמתנה של המשתמשים ומאפשרת טעינת קומפוננטות במקביל, מה שתורם לשיפור הביצועים הכלליים של האפליקציה.

בתמונה ניתן לראות כיצד סטרימינג מאפשר רינדור במקביל של קומפוננטות שונות, במקום רינדור סדרתי שבו כל קומפוננטה צריכה להמתין שהקומפוננטה הקודמת תסתיים לפני שתתחיל לטעון. בעזרת סטרימינג, ניתן להטעין את הקומפוננטות ברגע שהן מוכנות, כך שמשתמשים יכולים לראות חלקים מהדף מהר יותר, מה שמשפר את חווית המשתמש. סטרימינג מובנה ב-App Router של Next.js באופן אוטומטי!
לקבלת מידע נוסף, אתם מוזמנים לבקר בדוקומנטציה של Next.js
היתרונות של Client Components
אינטראקטיביות (Interactivity)
קומפוננטות צד לקוח יכולות להשתמש ב-state, כמו useState לדוגמה, ב-effects כמו useEffect, ו-event listeners כמו onClick. זה מאפשר להן לספק משוב מיידי למשתמש ולעדכן את ממשק המשתמש בזמן אמת. לדוגמה, כפתורים שמשנים צבע כאשר המשתמש לוחץ עליהם, או טפסים שמגיבים מיידית להזנת הנתונים.
גישה ל-API של הדפדפן
קומפוננטות צד לקוח יכולות לגשת ל-API של הדפדפן, כמו geolocation לאיתור מיקום המשתמש או localStorage לשמירת נתונים מקומיים. זה מאפשר לקומפוננטות לספק חוויות משתמש מותאמות אישית ולשמור מידע מקומי בצורה יעילה.
לקבלת מידע נוסף, אתם מוזמנים לבקר בדוקומנטציה של 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. האפשרות שלנו להחליט מה ייתרנדר בצד השרת ומה בצד הלקוח מורידה עומס מהדפדפן ומאיצה את טעינת האתר.

סיכום
Next.js מאפשרת לנו לחשוב מחדש על הדרך בה אנו מרנדרים את האפליקציות שלנו ולהתאים את תהליך הרינדור בהתאם לצרכים של כל רכיב. Server Components מאפשרים להקטין את עומס הקוד בצד הלקוח ולשמור על מידע רגיש בשרת, בעוד Client Components מאפשרים להוסיף אינטראקטיביות ואינטגרציה עם הדפדפן. שילוב נכון בין שתי הגישות - Server Components כברירת מחדל, Client Components רק לעלים אינטראקטיביים - יכול לשפר משמעותית את ביצועי האפליקציה ולהעניק חוויית משתמש טובה יותר.
שאלות נפוצות
מה זה 'use client' ואיפה לשים אותו
'use client' היא הוראה (directive) שצריכה להופיע בשורה הראשונה של קובץ הקומפוננטה, לפני כל import. היא מסמנת את הקומפוננטה ואת כל הקומפוננטות שמיובאות ממנה כ-Client Components. אין צורך להוסיף 'use client' לכל קומפוננטה - מספיק לשים אותה בקומפוננטה הראשונה בעץ שצריכה להיות בצד הלקוח, וכל הצאצאים שלה יקבלו את הסיווג אוטומטית.
האם Server Components תומכות ב-useState וב-useEffect
לא. Server Components לא תומכות ב-useState, useEffect, useReducer או כל hook אחר שדורש state או lifecycle בצד הלקוח. הן גם לא יכולות להשתמש ב-event handlers כמו onClick. אם אתם צריכים hook כזה, הקומפוננטה חייבת להיות Client Component עם 'use client'. Server Components מיועדות לתוכן שלא משתנה בצד הלקוח.
מה ההבדל בין Server Components ל-Server-Side Rendering (SSR)
SSR קלאסי מרנדר את הקומפוננטה בשרת ושולח את ה-HTML ללקוח, אבל גם שולח את כל ה-JavaScript של הקומפוננטה ל-hydration בדפדפן. Server Components לעומת זאת לא שולחות JavaScript ללקוח כלל - הקוד שלהן נשאר על השרת. זאת אומרת שגודל ה-bundle של הלקוח קטן משמעותית, ושאפשר להשתמש בקוד שלא יעבוד בדפדפן (גישה ישירה ל-DB, secrets, וכן הלאה).
האם אפשר להשתמש ב-Server Components בלי Next.js
טכנית כן, אבל בפועל לא מומלץ. Server Components הן תכונה של React שדורשת תשתית מיוחדת ב-bundler וב-runtime. Next.js (App Router), Remix ו-frameworks אחרים מספקים את התשתית הזו מובנית. אם אתם משתמשים ב-React לבד עם Vite או Create React App (שכבר deprecated), Server Components לא יעבדו. ב-Next.js הם זמינים מאז גרסה 13.
מתי כדאי להשתמש ב-'use server' בנוסף ל-'use client'
'use server' מסמנת פונקציה כ-Server Action - פונקציה שתמיד תרוץ בשרת, גם כשקוראים לה מ-Client Component. שימוש טיפוסי: טפסים שמבצעים מוטציה ב-DB ישירות בלי לכתוב route handler נפרד, או פעולות עם secrets שאסור שיגיעו ל-client. השתמשו ב-'use server' מתוך Client Component כדי להעביר לוגיקה רגישה לשרת, ב-'use client' כדי לסמן את הקומפוננטה עצמה כצד-לקוח.
