کامپایلر ریاکت رو روشن کردم؛ چیا شکست
خلاصهٔ کاملتر
تو اکتبر ۲۰۲۵ کامپایلر ریاکت نسخهٔ ۱.۰ بهصورت پایدار منتشر شد، با این وعده که دیگه لازم نیست کدبیس رو پر از useMemo و useCallback کنی. نویسنده میگه این خبر واکنشهای دوگانهای تو جامعهٔ ریاکت ساخت و خودش تصمیم گرفت کامپایلر رو روی یه پروژهٔ واقعی Next.js فعال کنه و هر هشدار و هر چیزی که شکست رو مستند کنه.
کامپایلر در اصل یه پلاگین Babel هست که جریان دادهٔ اپ رو تحلیل میکنه و مموایزیشن رو خودکار انجام میده. برای هر کامپوننت یه آرایهٔ کش تخت میسازه که با یه هوک داخلی به اسم _c بهش دسترسی داره، و خروجیش دقیقتر از React.memo عمل میکنه. شرطش اینه که کدت قوانین ریاکت رو رعایت کنه؛ اگه جایی آبجکت رو مستقیم mutate کرده باشی یا به رفرنسهای ناپایدار تکیه کرده باشی، حالا به باگ واقعی تبدیل میشه یا کامپایلر بیصدا از بهینهسازیش صرفنظر میکنه.
به گفتهٔ نویسنده جدیترین مشکل، فریز شدن پیشنمایش زندهٔ یه فرم بود. تابع watch() از React Hook Form به interior mutability تکیه میکنه و کامپایلر نمیتونه امن مموایزش کنه، برای همین ریرندرها قطع میشدن. راهحلش این بود که با دایرکتیو "use no memo" اون بخش رو از مموایزیشن کامپایلر مستثنا کنه:
function useFormCompat(props) {
"use no memo";
return useForm(props);
}یه مورد دیگه هم useCallback توی هندلر کلیک یه کامپوننت چارت بود. نویسنده میگه وقتی حذفش کرد، زیر بار دادههای قدیمی (stale) توی هندلرها ظاهر شد. این باگ کامپایلر نبود؛ فقط یه مشکل تایمینگ بود که useCallback با پایدار نگهداشتن identity هندلر پنهونش کرده بود، پس آگاهانه هوک رو برگردوند سر جاش.
نویسنده هشدار میده که نشان ✨ توی DevTools رو نباید سیگنال درستی حساب کنی: این نشان فقط یعنی کامپایلر کامپوننت رو پردازش کرده، نه اینکه بهینهسازی موفق بوده. حتی یه کامپوننتی که prop رو mutate میکرد و لینتر بهش ایراد گرفت، بازم نشان رو نشون میداد.
جواب سؤال «همهٔ useMemo و useCallbackها رو پاک کنم؟» از نظر نویسنده اینه: آره، ولی نه یهو. کامپایلر هوکهای موجود رو پاک نمیکنه، دورشون کار میکنه، پس اپ نمیشکنه؛ ولی نگهداشتنشون بیدلیل یعنی از دستدادن پرفورمنس. جاهایی که باید نگهشون داری: وقتی یه کتابخونهٔ ثالث به identity تابع وابستهست (چارتها، سیستمهای canvas)، وقتی مستقیم به DOM API یا SDK بیرونی listener وصل میکنی، یا وقتی یه محاسبهٔ واقعاً سنگین رو پروفایل کردی.
نکات کلیدی:
- کامپایلر ریاکت یه پلاگین Babel هست که مموایزیشن رو خودکار و دقیقتر از React.memo انجام میده.
- کتابخونههای با interior mutability مثل React Hook Form با دایرکتیو "use no memo" یا یه هوک wrapper باید مستثنا بشن.
- حذف useCallback میتونه باگهای تایمینگ پنهان (مثل stale data) رو رو کنه.
- نشان ✨ توی DevTools فقط یعنی کامپایلر وصله، نه اینکه کامپوننت واقعاً بهینه شده.
- اول لینترولهای eslint-plugin-react-hooks رو فعال کن، بعد کامپایلر؛ و حتماً تست E2E داشته باش.




