Lighthouse 100 بدون Next.js؛ درس از یک مهاجرت واقعی به Hono
نویسنده: آرش لطیفی
چرا حتی صفحه کاملا استاتیک با Next.js هم runtime JS داره، چطور نویسنده bloffy به ۱۰۰ کامل رسید و چه چیزی برای سایت خودت قابل استفادهست.
TL;DR — برای یه بلاگ کاملا استاتیک، Next.js حتی بدون هیچ client component هم چند صد کیلوبایت runtime و hydration payload میفرسته؛ یه مهاجرت واقعی به Hono همه Lighthouseها رو ۱۰۰ کرد، زمان build حدود ۴۰٪ کم شد و long task از ۳۰۹ms به ۶۸ms رسید.
اتفاق چی بود؟
روز ۲۰۲۶-۱۰-۲۶ یه پست با عنوان «Removing Next.js Got My Blog to 100 on Every Lighthouse Category» در Hacker News بالای ۱۶۰ امتیاز گرفت. نویسنده یه بلاگ شخصی با Next.js 16.1.6 ساخته بود، همه توصیههای رسمی رو رعایت کرده بود (ISR، کش، بهینهسازی تصویر با Cloudflare Image Transformations) و نتیجه Lighthouse خوب بود — ولی نه ۱۰۰.
مشکل از کجا بود؟ گزارش Lighthouse میگفت حجم زیادی legacy JavaScript هست که اصلا کد خود نویسنده نبود؛ runtime خود فریمورک بود.
چرا حذف client componentها هم کافی نبود؟
اینجا جالبترین بخش داستانه. نویسنده به عنوان آزمایش همه client componentها رو حذف کرد و فقط Server Component گذاشت — نمره هیچ تغییری نکرد. چرا؟ چون Next.js برای صفحات استاتیک هم همیشه اینها رو نگه میداره:
- chunkهای client runtime و کد hydration
- payload مربوط به روتر (RSC payload)
حتی next/link و next/image خودشون 'use client' هستن؛ داشتن همین دو تا کافیه که runtime لود و hydration اجرا بشه. اگر اونها رو هم حذف کنی، runtime خود App Router (روتر و error boundaryها) باقی میمونه و راه رسمی برای صفر کردنش وجود نداره. راهحل نویسنده هک بود: حذف اسکریپتها از HTML رندرشده. اونجاست که به این نتیجه رسید: «اگر قراره این کارو بکنم، اصلا چرا Next.js دارم؟»
اعداد نهایی: کد استفادهنشده از حدود ۲۳۰ کیلوبایت به ۴۰۷ بایت رسید (کل JS خروجی صفر). زمان build هم حدود ۴۰٪ کاهش پیدا کرد. long task قبل از رندر روی Next.js برابر ۳۰۹.۳ms بود که با Hono به ۶۸.۰۱ms رسید — حدود ۷۸٪ بهبود.
جدول: کی Next.js لازمه، کی لازم نیست
| نوع سایت | Next.js منطقیه؟ | چرا | | --- | --- | --- | | بلاگ / مستندات / لندینگ استاتیک | معمولا نه | هیچ تعامل واقعی نداری؛ فقط runtime JS و hydration اضافه پرداخت میکنی | | فروشگاه با سبد و چکاوت زنده | بله | state پیچیده، پرداخت، ISR و API routeها واقعا استفاده میشن | | داشبورد / اپ داخلی | بله | تعامل بالا خودش JS میخواد؛ فریمورک بهرهوری میده | | سایت چندزبانه با SEO سنگین | بستگی داره | اگر صفحات عملا استاتیکن، SSG سبکتر کافیه؛ برای بخش اپ Next.js بمونه |
نکته مهم: نویسنده پنل مدیریت همون بلاگ رو همچنان با Next.js ساخته. انتخاب یا حذف Next.js یه تصمیم سراسری نیست؛ تصمیمی برای هر سطح از اپه.
برای اندازهگیری واقعی (نه فقط ابزار آنلاین) میتونی از CLI استفاده کنی:
و برای بهینهسازی تصویر با Cloudflare Image Transformations کافیه پارامترها رو به URL تصویر اضافه کنی:
https://example.com/cdn-cgi/image/width=800,format=avif/photo.jpg
برای سایت خودت چی کار میتونی بکنی؟
- [ ] برو pagespeed.web.dev و بخش «Reduce unused JavaScript» رو ببین — اعداد دقیق بنویس
- [ ] توی Next.js چک کن چقدر از bundle برای صفحاتی که هیچ تعاملی ندارن میره
- [ ] اگر صفحه استاتیکته، client componentها رو فقط برای نقاط واقعا تعاملی نگه دار
- [ ] کش و CDN رو قبل از عوض کردن فریمورک درست کن — نویسنده این کار رو اول کرد و نمره خوب ولی نه ۱۰۰ گرفت
- [ ] فریمورک سبک بدون hydration مثل Hono یا Hugo رو برای بخش کاملا استاتیک بسنج
FAQ
Q: یعنی Next.js بده؟
نه. پست خودش صریح میگه برای اپهای تعامل محور Next.js میتونه انتخاب خیلی خوبی باشه و بخش مدیریتی همون بلاگ هم با Next.js نوشته شده. بحث فقط درباره صفحاتی هست که هیچ JS لازم ندارن.
Q: Lighthouse ۱۰۰ واقعا مهمه؟
نمره ۱۰۰ بهخودیخود هدف تجاری نیست، ولی مسیر رسیدنش فهرست دقیقی از بدهبستانهای پرفورمنس میده. حذف runtime اضافه یعنی LCP سریعتر، مخصوصا روی موبایل و اینترنت ضعیف.
Q: جایگزینهای سبک چیا هستن؟
توی بحث HN تجربههای مختلفی اومد: Hugo روی GitHub Pages با نمره ۱۰۰ بدون هیچ تلاشی برای پرفورمنس، SvelteKit با نمرههای کامل، و حتی HTML خام و vanilla JS. الگوی مشترک: هرچی کمتر JS، یک دسته کامل از مشکلات پرفورمنس کلا حذف میشه.