אחד הקונספטים היותר מעניינים בעולמות של FRONT END DEVELOPMENT זה SSR . שמעתי על זה לפני זמן רב אבל לא ייחסתי לזה חשיבות בזמנו. ועם הזמן, שמעתי על זה יותר, וכן עשיתי כמה התנסויות בשביל להבין על מה כל המהומה. יש לי לא מעט מה לומר על הנושא ואשתדל להיות מתומצת וענייני בפוסט הזה על מנת שכל אחד שיקרא את הפוסט יבין מהם היתרונות והחסרונות, וגם קצת פרקטיקה בשביל ללכלך קצת את הידיים. ורק אומר במשפט אחד "SSR הוא פתרון מדהים".
אציין כי אני כותב ספציפית על SSR עם react. וכן אציג דוגמאות בעבודה עם create next app כלומר next js
ההבדלים בין SSR לקונספט המוכר CSR
בשביל להבין טוב יותר את ההבדלים אציג תרשים של התהליכים השונים בטעינה של הclient:

אז כפי שאפשר לראות, בטעינה ראשונה של העמוד יש מספר הבדלים , ואפילו דיי משמעותיים, כך שזמן הטעינה עד לקבלת תצוגה יהיה משמעותית קצר יותר עם SSR. אבל יש לזה מחיר כמובן כי SSR יהיה יקר יותר מבחינת עבודת צד השרת. אבל לפני שנדבר על היתרונות והחסרונות, ברצוני לתת את הקרדיט ברמת UX לעבודה עם SSR. אכן תקבלו ביצועים טובים יותר עבור הגולשים שלכם ותהיה תחושה טובה יותר כך שתתקבל התצוגה הרצויה.
עכשיו שהבנו את התהליכים בואו נדבר על ההבדלים
עם SSR:
- תצוגה מהירה יותר וללא מצבים מביכים של blank page
- מנועי חיפוש יקבלו fully html page
- יקר יותר מבחינת קריאות צד שרת
עם CSR:
- משך טעינה ארוך יותר ואיבוד קבצי JS בקליינט שלוקחים זמן
- מנועי החיפוש יתקשרו לאנדקס את העמודים שלכם מכוון שנבנים במהלך הזמן על ידי הJS
- פחות קריאות מצד שרת
- מהיר יותר אחרי הטעינה הראשונה (cache mechanism)
אז כפי שניתן לראות לכל קונספט יש יתרונות וחסרונות. ואם נרצה לבחור קונספט באופי העבודה שלנו, איפשהו, זה מתחיל להיות מבלבל…
מתי יהיה עדיף לבחור בSSR ומתי עדיף לבחור בCSR
לרוב SSR יתאים יותר לאתרים שהם static pages based למשל: אתרי לימודים, חנויות או אפליקציות עם מעט עמודים וכמובן התחשבות במנועי חיפוש. וCSR יהיה טוב יותר באפליקציות דינאמיות כמו רשתות חברתיות, מערכת הודעות וכו..
בעידן של היום האפליקציות מגוונות ולא תמיד יהיו רק סטטיות או רק דינאמיות, אז מה עושים?
יש פתרון אולטימטיבי! לשלב בין השניים.
לדעתי, בימינו, שאתם בונים אפליקציה כלשהי בreact תשקלו לפחות חלק ממנה לעשות שימוש ב SSR.
עם next js תקבלו סט מוכן לעבודה היברידית עם הקונספטים הללו, תוכלו בקלות להגדיר "use client" עבור רכיבים שלא תרצו שיתרנדרו בצד שרת. ישנם כל מיני טכניקות לכתיבה עם nextjs שככל הנראה אציג בפוסטים נוספים, כמו כן כמובן שהייתי ממליץ לעבור על הדוק שלהם וללמוד יותר על מבנה הפרויקט ועבודה נכונה של רכיבים SSR ורכיבים CSR.
דיברנו המון, זה הזמן לקצת פרקטיקה
אציג פה דוגמה פשוטה, של כמה קבצים בודדים מהפרויקט (רשימת משימות todo list) , עם שימוש ב next. יכול להיות שהבחנתם בכל מיני דברים שלא דיברנו עליהם כמו prisma . למעשה next נותנת לנו סביבת עבודה שלמה לפיתוח fullstack . כולל חיבור לדטהבייס, אבל נכון לפוסט הזה בואו נתעלם מכל הדברים האחרים (ונשאיר אותם לפוסטים הבאים בנושא next 🙌).
import Link from 'next/link' import { prisma } from './db' import TodoItem from '@/components/TodoItem'; function getTodos() { return prisma.todo.findMany(); } async function toggleTodo(id: string, completed: boolean) { "use server"; const todo = await prisma.todo.findUnique({ where: { id } }); await prisma.todo.update({ where: { id }, data: { completed } }); return todo; } export default async function Home() { const todos = await getTodos(); return ( <> <header className='flex justify-between items-center mb-4'> <h1 className='text-2xl'>Todos</h1> <Link href='/new' className=' border border-slate-600 rounded-md px-4 py-2 rounded-md text-slate-100 hover:bg-slate-600 hover:text-slate-200 '>New</Link> </header> <ul className='pl-4'> {todos.map((todo) => <TodoItem toggleTodo={toggleTodo} key={todo.id} {...todo} />)} </ul> </> ) }
קובץ זה ירונדר מצד שרת SSR וכפי שניתן להבחין , נעשית כאן קריאה לדטהבייס ושימוש אסינכרוני בפונקציות מה שפחות קורה בCSR. וכן גם אם תנסו להדפיס איזה קונסול, לא תקבלו אותו כן מכוון שכל הקוד הזה רץ בצד שרת. דבר חשוב שכן יש לשים לב, זה התגית "use server" שמציינת לnext כי מדובר ברכיב שהוא SSR
לעומת רכיב שהוא CSR, שאפשר להבין כי התגית תהיה : "use client" וכן אם תבחרו להדפיס כאן קונסול לוג כן תקבלו את ההדפסה שלו לקונסול כי זהו רכיב קליינט "רגיל" של ריאקט.
"use client"; type TodoItemProps = { id: string; title: string; completed: boolean; toggleTodo: (id: string, completed: boolean) => void; } function TodoItem({ id, title, completed, toggleTodo }: TodoItemProps) { return (<li className="flex gap-1 items-center"> <input defaultChecked={completed} type="checkbox" id={id} className="cursor-pointer peer" onChange={e => toggleTodo(id, e.target.checked)} /> <label htmlFor={id} className="cursor-pointer peer-checked:line-through peer-checked:text-slate-500">{title}</label> </li>); } export default TodoItem;
לסיכום Server Side Rendering with React
כמתכנת frontend מנוסה אני בהחלט ממליץ לעבוד עם קונספט של SSR ואם לא בא לכם לפחות תתנסו בו ותכירו אותו לרמה סבירה , השימוש בSSR הולך וגדל בתקופה האחרונה ובטח שכן אפשר לעשות שימוש HYBRID ולנתב את הרכיבים לפי צורך. כמו כן next הוא framework מבוסס SSR אבל אפשר לכתוב SSR גם בלי next כמובן. אפשר להגדיר לבד את השימוש בקונספט של SSR ללא צורך בframework. כמו כן next מביא איתו עוד קונספטים חדשים ומעניינים SSG, ISR ששווה לעקוב אחריהם , וכן אדבר על זה בפוסטים הבאים בנושא next.
בהצלחה 🐊🤩