توسعه نرم‌افزار

بهینه‌سازی کارایی لاراول: یک واکاوی عمیق

نویسنده: Hadi ZareZadeh۲۷ اسفند ۱۴۰۴۳۵۶۱ بازدید
بهینه‌سازی کارایی لاراول: یک واکاوی عمیق

اگر یک مقاله کارایی لاراول خوانده‌اید، همه‌شان را خوانده‌اید: eager load کن، کش کن، صف بزن. همه درست، همه ناقص. این گذر عمیق‌تر است — الگوها، ابزارها و گردش کار پروفایلینگی که وقتی یک اپلیکیشن واقعاً در تولید کند است استفاده می‌کنم، نه در یک پست وبلاگ بنچمارک.

مسئله N+1 و فراتر از آن

eager loading مسئله کلاسیک N+1 را حل می‌کند، اما مراقب گونه‌های پنهانش باشید: lazy loading در ویوهای Blade، N+1 در jobهای صف‌شده که مجموعه‌ها را یکی‌یکی پردازش می‌کنند و «eager loading همه چیز» که نیمی از پایگاه داده را به حافظه می‌کشد.

// بد: همه ستون‌ها و همه ردیف‌های مرتبط را بارگذاری می‌کند
Course::with('lessons', 'instructor', 'reviews')->get();

// بهتر: آنچه بارگذاری می‌کنید را محدود کنید
Course::with([
    'lessons:id,course_id,title,duration',
    'instructor:id,name',
])->select('id', 'title', 'instructor_id')->get();

با راهبرد کش کنید، نه با چکش

چیزهایی را کش کنید که زیاد خوانده می‌شوند و کم تغییر می‌کنند. کلیدهای کش را بر اساس دامنه برچسب بزنید تا بتوانید دقیق بی‌اعتبار کنید:

Cache::tags(['courses', "course:{$id}"])
    ->remember("course:{$id}:show", 3600, fn () => $course->load(...));

وقتی دوره به‌روز شد، برچسبش را پاک کنید. داده مخصوص کاربر را با یک کلید سراسری کش نکنید، مگر اینکه از سرو کردن داشبورد یک کاربر به دیگری لذت ببرید.

صف‌ها به‌درستی

صف‌ها فقط برای ایمیل نیستند. برای هر چیزی هستند که نباید پاسخ HTTP را مسدود کند. اما یک صف پر از jobهای کند و شکست‌خورده بدتر از نبود صف است — jobهای شکست‌خورده را مانیتور کنید، timeout بگذارید و برای کار سنگین در برابر سبک از صف‌های اختصاصی استفاده کنید.

بهینه‌سازی‌های تولید

  • php artisan config:cache و route:cache در تولید — غیرقابل‌مذاکره.
  • OPcache فعال با حافظه کافی.
  • بهینه‌سازی autoloader کامپوزر: composer install --optimize-autoloader --no-dev.
  • برای پردازش دیتاست بزرگ به‌جای get() از chunk() یا lazy() استفاده کنید.

ابزارهای پروفایلینگ

Laravel Telescope در staging تعداد کوئری‌ها و درخواست‌های کند را شکار می‌کند. در تولید، از لاگ‌گیری ساختاریافته با زمان‌بندی کوئری یا یک APM اختصاصی استفاده کنید. هدف پیدا کردن آن یک کوئری یا یک endpoint است که ۸۰٪ زمان شما را می‌خورد — اول آن را درست کنید.

اشتباهات رایج

  • کش بدون بی‌اعتبارسازی. باگ‌های داده کهنه از صفحات کند سخت‌تر دیباگ می‌شوند.
  • بهینه‌سازی محلی. لپ‌تاپ شما تولید نیست. جایی پروفایل بگیرید که کاربران واقعاً می‌زنند.
  • اضافه کردن Redis قبل از درست کردن کوئری‌ها. یک لایه کش روی یک کوئری خراب فقط پاسخ‌های غلط را سریع‌تر می‌کند.

بهترین شیوه‌ها

  • اول با Telescope یا APM اندازه بگیرید؛ گلوگاه واقعی را بهینه کنید.
  • در تست‌ها یک بودجه تعداد کوئری برای هر درخواست بگذارید تا پسرفت‌های N+1 را بگیرید.
  • لاگ کوئری‌های کند را هفتگی در کنار لاگ‌های اپلیکیشن بازبینی کنید.

جمع‌بندی

کارایی لاراول در جزئیات برده می‌شود: eager loadهای محدودشده، کش عمدی، طراحی درست صف و کانفیگ تولید. قبل از بهینه‌سازی پروفایل بگیرید، قبل از افزودن کش کوئری‌ها را درست کنید و آنچه تحویل می‌دهید را مانیتور کنید. همین امروز روی کندترین مسیرتان لاگ‌گیری کوئری را فعال و کوئری‌ها را بشمارید — همان عدد می‌گوید اول چه چیزی را درست کنید.