Foad Labs
82 subscribers
46 photos
2 videos
2 files
45 links
Building modern web experiences.
React • Next.js • TypeScript

🪐 DM For collaborates: @foad_ebrahiml
🌐 Personal website: https://foad-ebrahimi.ir
Download Telegram
یکم ناخوش احوالم نتونستم کتاب بخونم و براتون مطالبش رو بزارم
فردا جبرانش انشالا ❤️
🔥1
🔥2
👌2🗿1
🎫 ایونت معرفی ۴ ماه کارورزی فشرده توی آوینوکس
که دیروز برگزار شد و به نسبت ایونت جالب و مفیدی بود

اصل موضوع یک دوره ۴ ماهه کارورزی توی کارخونه نوآوری آوینوکس بود که تحت نظر شرکت مادر یعنی آواپرداز قرار داشت

و به ۶ تا آزمایشگاه مختلف و تخصصی تقسیم میشد این دوره و طی نظر منتور های متخصص شما مباحث تئوری رو یاد میگرفتین و بعد توی آزمایشگاه به صورت تیمی و عملی روی پروژه‌های شبیه سازی شده واقعی کار میکردین

و اینم بگم که تمام مراحلشون از ثبت نام بگیر تا پایان دوره یک شبیه سازی کامل از استخدام بود یعنی شما در طول هفته باید ۴۵ ساعت توی کاخونه مثل شرکت‌ها حضور داشته باشی و غیب های موجه میتونی داشته باشی و همینطور
مرخصی و ...


درکل دوره کارورزی خوب و تمیزیه برای افرادی که میخان حوضه مورد علاقشونو پیدا کنن و توی یه فیلد خاص با افراد هم هدف خودشون ارتباط بگیرن و جلو برن.
1🔥1
🚀 TypeScript 7
منتشر شد؛ بزرگ‌ترین تغییر تاریخ TypeScript!

مایکروسافت در TypeScript 7، کامپایلر و Language Server را از پایه‌ی قبلی به Go پورت کرده تا به‌صورت Native اجرا شوند. نتیجه؟ عملکردی که در بسیاری از پروژه‌ها تا ۱۰ برابر سریع‌تر از TypeScript 6 است.

مهم‌ترین تغییرات:

- کامپایلر Native مبتنی بر Go
- 🚀 تا ۱۰ برابر افزایش سرعت Type Checking و Build
- 🧠 IntelliSense و Autocomplete سریع‌تر در VS Code
- 💾 مصرف حافظه کمتر در پروژه‌های بزرگ
- 🔄 استفاده از Parallelism برای پردازش هم‌زمان و عملکرد بهتر

نکته جالب اینجاست که تیم TypeScript این پروژه را بازنویسی کامل نکرده؛ بلکه منطق کامپایلر فعلی را به Go پورت کرده تا سازگاری حفظ شود و در عین حال از سرعت اجرای Native بهره ببرد.

اگر روی پروژه‌های بزرگ React، Next.js یا Node.js کار می‌کنید، این نسخه می‌تواند زمان Build و Type Checking را به شکل محسوسی کاهش دهد.

💬 شما بعد از انتشار TypeScript 7 مهاجرت می‌کنید یا فعلاً روی نسخه‌های قبلی میمونین؟
اینم نمودار تغییراتش که واقعا حرفی نمیمونه
حتما یکی از پروژهامو انتقال میدم به تایپ ۷ و نتیجه بیلد قبل و بعدش رو میزارم براتون
2
برگشتیم 🙌🏻
2
👀 یه سوال ساده :
اگه یه کامپوننت رو با React.memo بپیچونید، مطمئنین دیگه بی‌خودی رندر نمیشه؟
جواب کوتاه : نه همیشه.
React.memo فقط پراپ‌ها رو با === مقایسه میکنه. حالا اگه یکی از پراپ‌هاتون یه object یا function باشه که هر بار توی parent از نو ساخته میشه، از نظر رفرنس با دفعه قبل فرق داره — حتی اگه محتواش عین هم باشه.
نتیجه؟ memo هیچ کاری نمیکنه و کامپوننت بازم رندر میشه.

راه‌حلش اینه که خود رفرنس رو ثابت نگه دارین، نه اینکه فقط فرزند رو memoize کنین. برای function از useCallback و برای object/array از useMemo کمک بگیرین.

منبع رسمی
👍2🔥1
⚡️ نکته سریع امروز
useCallback
یه function رو بین رندرها ثابت نگه میداره، useMemo یه مقدار محاسبه‌شده رو (object، array، عدد سنگین).
در واقع هر دو زیر hood یه چیزن. useCallback(fn, deps) دقیقاً معادله با useMemo(() => fn, deps).

نکته‌ای که خیلیا ازش غافلن :
اگه یه محاسبه سنگین نیست و صرفاً یه رشته یا عدد ساده‌ست، اصلاً نیازی به useMemo نیست. هزینه خود hook (نگه‌داشتن dependency array و مقایسه‌ش) گاهی از خود محاسبه گرون‌تره.
قانون کلی : فقط وقتی استفاده کنین که یا محاسبه واقعاً سنگینه، یا میخواید رفرنس رو برای memo کردن یه فرزند ثابت نگه دارین.

⚠️ یه نکته جانبی هم بگم

اگه پروژه‌تون داره از React Compiler استفاده میکنه، عملا نیازی به useMemo و useCallback دستی ندارین کامپایلر خودش تحلیل میکنه کجا باید memoize بشه و خودکار اعمال میکنه — دقیق‌تر از چیزی که ما دستی مینویسیم.
ولی واقعیت اینه که اکثر پروژه‌های production هنوز روی React 18 هستن و کامپایلر رو adopt نکردن. پس دونستن این مفاهیم هنوزم ضروریه.

useMemo
useCallback
reactCompiler
🔥2
🚀 روی یه پروژه واقعی کار میکردم که LCP‌ش رو ۳.۲ ثانیه بود. الان رو ۰.۹ ثانیه‌ست. بگم چیکار کردیم؟
سه تا تصمیم بیشترین تاثیر رو داشت :
۱. فونت
فونت اختصاصی پروژه باعث میشد صفحه یه مدت کاملاً سفید بمونه (FOIT). با display: swap و preload کردن فایل فونت، مرورگر اول با فونت fallback رندر میکنه و بعد جایگزین میکنه. همین یه چیز، حدود ۶۰۰ میلی‌ثانیه از رندر اول کم کرد.
۲. تصویر Hero
تصویر Hero که خودش عنصر LCP بود، با loading="lazy" بارگذاری میشد! یعنی مرورگر دیرتر از حد لازم میرفت سراغش. یه priority گذاشتیم روش و تموم شد.
۳. Code splitting هدفمند
lazy import کردن همه چیز اشتباهه. کامپوننت‌های above-the-fold رو static گذاشتیم، فقط چیزایی که پایین صفحه بودن (مودال‌ها و...) رو dynamic کردیم.

Optimize LCP
next/image
3💯2👌1
Foad Labs
👀 یه سوال ساده : اگه یه کامپوننت رو با React.memo بپیچونید، مطمئنین دیگه بی‌خودی رندر نمیشه؟ جواب کوتاه : نه همیشه. React.memo فقط پراپ‌ها رو با === مقایسه میکنه. حالا اگه یکی از پراپ‌هاتون یه object یا function باشه که هر بار توی parent از نو ساخته میشه،…
📌 تکمیل پست قبلی درباره React.memo

بعد از انتشار این پست توی لینکدین، یکی از دوستان یه نکته خوب رو یادآوری کرد که بد نیست بهش اشاره کنیم.

اول اینکه React.memo در واقع پراپ‌ها رو با Object.is مقایسه می‌کنه، نه صرفا ===. تفاوتش تو اکثر سناریوها ناچیزه، اما از نظر فنی این همون مکانیزمیه که React استفاده می‌کنه.

نکته دوم و مهم‌تر اینکه React.memo یه پارامتر اختیاری به اسم arePropsEqual داره. با این تابع می‌تونین خودتون مشخص کنین که دو سری پراپ چه زمانی «برابر» محسوب بشن.

مثلا فرض کنین از API هر بار یه آبجکت جدید دریافت می‌کنین :

const UserCard = React.memo(
UserCardComponent,
(prevProps, nextProps) => prevProps.user.id === nextProps.user.id
);

توی این حالت، حتی اگه رفرنس آبجکت عوض شده باشه، تا وقتی id تغییر نکرده باشه، کامپوننت دوباره رندر نمیشه.

اما یه نکته مهم 👇

arePropsEqual
قرار نیست جای useMemo و useCallback رو بگیره. اگر والد هر بار object یا function جدید بسازه، بهتره اول دلیلش رو برطرف کنین و رفرنس‌ها رو پایدار نگه دارین. نوشتن مقایسه‌ی سفارشی برای هر کامپوننت هم هزینه نگهداری داره و اگر اشتباه پیاده‌سازی بشه، حتی می‌تونه باعث باگ بشه.

خلاصه اینکه:
React.memo
برای جلوگیری از رندرهای غیرضروری مفیده.
useMemo و useCallback
برای ثابت نگه داشتن رفرنس‌ها هستن.
arePropsEqual
هم ابزاریه برای سناریوهای خاص، نه راه‌حل پیش‌فرض.

بهینه‌سازی توی React بیشتر از اینکه حفظ کردن هوک‌ها باشه، درک نحوه‌ی مقایسه‌ی پراپ‌ها و جریان رندر شدنه.
🔥1
🤔 این دوتا یه مسئله رو حل میکنن ولی فلسفه‌شون کاملاً فرق داره.
🔄 Redux Toolkit
هنوز به slice و reducer نیاز داره. حتی با RTK، ساختار قابل پیش‌بینیه ولی حجیم‌تره.
📦 Zustand
با یه تابع create، کل store رو میسازه، بدون Provider اجباری، بدون boilerplate اضافه.
⚡️ از نظر re-render هم هر دو با selector کار میکنن، پس اونجا فرقی نیست.
🎯 سوال اصلی اینه : تیم چندنفره‌این و به قوانین سخت‌گیرانه و DevTools پیشرفته نیاز دارین؟ ← Redux Toolkit 🛠️
پروژۀ کوچیک تا متوسطه و سرعت توسعه اولویته؟ ← Zustand 🚀

منابع :
🔗 Zustand — Getting Started
🔗 Redux Toolkit — Quick Start
🔥2
⚙️ اکثر پیاده‌سازی‌های useDebounce که توی پروژه‌های مختلف دیدم، یه مشکل مشترک دارن :
کلین‌آپ ندارن!
بدون cleanup، هر بار که ورودی عوض میشه، تایمر قبلی هنوز فعاله و ممکنه callback قدیمی با state قدیمی اجرا بشه (stale closure).

دو نکته مهم :

همیشه generic تعریفش کنید تا برای هر نوع داده قابل استفاده مجدد باشه
delay
رو حتما توی dependency array بذارید وگرنه اگه تغییر کنه، hook متوجه نمیشه

منبع رسمی
👌2
🔴 چالش امشب
این کد یه infinite loop تولید میکنه خودتون دلیلش رو پیدا کنین

15 دقیقه دیگه جوابش رو میزارم همراه با راه‌حل

#Labs_Challenge
🔥1
جواب :
options
هر بار توی کامپوننت از نو ساخته میشه (یه object literal جدید)، پس رفرنسش هر رندر عوض میشه، useEffect دوباره اجرا میشه، یه رندر جدید اتفاق میفته... و این چرخه هیچوقت تموم نمیشه.
🟠 برای حل این مشکل سه تا راه‌حل داریم که توی تصویر ذکر شده

🟢 بهترین راه‌حل به context و منطق کامپوننتتون ستگی داره. اگه options ثابته، گزینه ۳ بهترینه چون اصلا هیچ هزینه‌ای نداره.
🔥1
مرسی از همه دوستان که توی چالش امشب شرکت کردن و نظرات خودشونو درمیون گذاشتن
فردا کلی محتوا و در آخرشب هم چالش داریم

شبتون پر از ایده‌های میلیون دلاری 😁❤️
🔥1
امروز رو اختصاص میدیم به خود Next.js و rendering strategies توی اون

مثل همیشه خوشحال میشیم نظرات و فکرهایی که به ذهنتون میاد رو با بقیه به اشتراک بزارین تا کنار همدیگه رشد کنیم ❤️

برو بریم
🔥1