
چرا admin-ajax.php سایت پرترافیک وردپرسی شما را کند میکند؟
چرا admin-ajax.php سایت پرترافیک وردپرسی شما را کند میکند؟
فرض کنید یک فروشگاه ووکامرسی دارید. کش را فعال کردهاید، تصاویر را فشرده کردهاید و در PageSpeed Insights هم نمرهی خوبی میگیرید. اما همین که ترافیک واقعی بالا میرود، مثلا در یک کمپین فروش، سرور زیر فشار میرود و گاهی سایت برای چند لحظه از دسترس خارج میشود. اگر این تجربه آشناست، مقصر اصلی احتمالا همان چیزی است که در این مقاله بررسی میکنیم: فایل admin-ajax.php.
چرا کش، این مشکل را حل نمیکند؟
افزونههای کش، نسخهی آمادهی صفحات را ذخیره میکنند تا سرور مجبور نباشد هر بار آنها را از نو بسازد. اما admin-ajax.php یک درخواست POST و کاملا پویا است؛ هر بار که فراخوانی میشود، وردپرس باید کامل بارگذاری شود و پاسخ تازه تولید کند. این درخواست از لایهی کش عبور میکند، چون اساسا برای همین منظور طراحی شده. به همین دلیل، سایتی که در ظاهر کاملا بهینه به نظر میرسد، همچنان میتواند زیر بار همین درخواستها از پا در بیاید.
برای درک بهتر این موضوع، منابع پردازشی سرور (معروف به PHP Worker) را میتوان به صندوقهای پرداخت یک فروشگاه تشبیه کرد؛ هر صندوق در هر لحظه فقط میتواند به یک مشتری رسیدگی کند. هر درخواست به admin-ajax.php، دقیقا مثل یک مشتری جدید، یکی از این صندوقها را برای مدتی اشغال میکند. وقتی تعداد این درخواستها زیاد شود، صندوقهای کمتری برای رسیدگی به بازدیدکنندههای واقعی سایت باقی میماند و همانجاست که کندی یا قطعی رخ میدهد.
پیش از هر چیز؛ مطمئن شوید مشکل واقعا از این دو منبع است
گاهی حجم بالای درخواست به admin-ajax.php ربطی به Heartbeat یا Cart Fragments ندارد و نتیجهی حملهی رباتی یا تلاشهای ورود مشکوک است. اگر لاگ سرور نشان میدهد این درخواستها از تعداد زیادی آدرس IP متفاوت و ناآشنا میآیند، نه از کاربران واقعی سایت، مشکل شما امنیتی است، نه بهینهسازی کد؛ و راهحلش هم فایروال یا محدودسازی نرخ درخواست است، نه تغییر تنظیمات Heartbeat یا Cart Fragments.
دو منبع اصلی درخواستهای admin-ajax.php
Heartbeat API
Heartbeat یک قابلیت داخلی وردپرس است که از پیشخوان مدیریت، هر پانزده تا شصت ثانیه یکبار به سرور سر میزند؛ برای کارهایی مثل ذخیرهی خودکار نوشته و جلوگیری از تداخل دو ویرایشگر همزمان. این درخواستها فقط از تبهای باز پیشخوان مدیریت ارسال میشوند، نه از سمت بازدیدکنندههای عادی سایت. اگر چند نفر همزمان در پیشخوان لاگین باشند و تب مرورگرشان باز بماند، تعداد این درخواستها میتواند در طول یک روز کاری قابل توجه شود.Cart Fragments ووکامرس
این یکی برخلاف Heartbeat، از سمت بازدیدکنندههای واقعی سایت ارسال میشود؛ برای اینکه مینیکارت هدر (تعداد و مبلغ سبد خرید) بهروز بماند، حتی وقتی کاربر وارد حساب کاربری نشده باشد. نکتهی مهم اینجاست: از نسخهی ۷.۸ ووکامرس، این اسکریپت دیگر بهطور پیشفرض در همهی صفحات اجرا نمیشود؛ فقط وقتی صفحه واقعا یک بلوک Cart Widget نمایش دهد، فعال میشود. اگر فروشگاه شما نسخهی قدیمیتر ووکامرس را دارد، یا قالب آن بصورت کلاسیک مینیکارت را در هدر همهی صفحات نشان میدهد، این درخواست همچنان در هر بازدید، حتی برای کاربرانی با سبد خرید خالی، اجرا میشود.
چطور بفهمیم مقصر واقعی کدام است؟
در تب Network مرورگر (یا افزونهی Query Monitor)، سایت را باز کنید و درخواستهای ارسالی به admin-ajax.php را پیدا کنید. محتوای درخواست را بررسی کنید:
- اگر پارامتر
action=heartbeatدارد، منبعش Heartbeat API است. - اگر آدرس آن شامل
wc-ajax=get_refreshed_fragmentsاست، منبعش Cart Fragments ووکامرس است.
برای دیدن تصویر کلیتر، لاگ دسترسی سرور (Access Log) را هم بررسی کنید؛ اکثر پنلهای هاست، امکان مشاهدهی تعداد درخواست به هر فایل را در بازهی زمانی مشخص میدهند. اگر تعداد درخواست به admin-ajax.php در ساعات پربازدید روز بهطور نامتناسبی از سایر فایلهای سایت بیشتر باشد، همین موضوع را تایید میکند.
در فروشگاه فرضی ما، چون بیشتر این درخواستها از بازدیدکنندههای واقعی و حتی کاربران بدون سبد خرید فعال میآمد، مشخص شد مشکل اصلی از Cart Fragments است، نه Heartbeat.
راهکار برای Heartbeat API
میتوان فاصلهی زمانی درخواستهای Heartbeat را با فیلتر رسمی وردپرس به نام heartbeat_settings افزایش داد؛ این فیلتر عددی بین پانزده تا صدوبیست ثانیه را میپذیرد. افزایش این فاصله، تعداد درخواستها را کاهش میدهد بدون آنکه خود قابلیت بهطور کامل از کار بیفتد. در برخی پروژهها، Heartbeat فقط در صفحهی ویرایش نوشته نگه داشته میشود و در بقیهی بخشهای پیشخوان غیرفعال میشود، چون بیشترین نیاز واقعی همانجاست.
راهکار برای Cart Fragments
روش رایج، متوقف کردن این اسکریپت در همهی صفحات بهجز سبد خرید و پرداخت است؛ جایی که بهروز بودن اطلاعات سبد واقعا ضروری است. این کار با متوقف کردن اسکریپت wc-cart-fragments از طریق هوک استاندارد enqueue اسکریپتهای وردپرس انجام میشود.
نکتهی مهم اینجاست: این راهکار یک هزینه هم دارد. اگر مینیکارت هدر سایت شما قرار است در همهی صفحات، حتی خارج از سبد خرید، تعداد و مبلغ را بهروز نشان دهد، متوقف کردن کامل این اسکریپت باعث میشود آن بخش دیگر بهطور خودکار بهروز نشود. برای همین، این تغییر معمولا باید همراه با یک جایگزین سبکتر (مثلا بهروزرسانی مینیکارت فقط در لحظهی افزودن محصول به سبد، نه در هر بارگذاری صفحه) پیادهسازی شود، نه صرفا حذف کامل قابلیت.
نتیجه در فروشگاه فرضی ما
بعد از محدودکردن Cart Fragments به صفحات سبد خرید و پرداخت، و افزایش فاصلهی Heartbeat در پیشخوان مدیریت، تعداد درخواستهای admin-ajax.php در طول روز بهشکل محسوسی کاهش پیدا میکند. نتیجه، پایداری بیشتر سرور زیر بار ترافیک واقعی است؛ حتی اگر نمرهی PageSpeed سایت، قبل و بعد این تغییر، تفاوت چندانی نشان ندهد. این دقیقا همان نکتهای است که تستهای آزمایشگاهی سرعت نمیتوانند نشانش دهند.
چرا این مشکل زیر ترافیک بالا خطرناکتر میشود؟
هر هاست وردپرسی، تعداد مشخصی PHP Worker در اختیار دارد؛ اینها را میتوان مثل صندوقدارهای یک فروشگاه در نظر گرفت که هرکدام فقط میتوانند همزمان به یک مشتری رسیدگی کنند. هر درخواست به سایت، از جمله هر بارگذاری صفحه و هر درخواست admin-ajax.php، یکی از این Workerها را برای مدتی اشغال میکند.
وقتی تعداد زیادی درخواست Cart Fragments یا Heartbeat همزمان وارد میشود، همهی Workerها میتوانند مشغول این درخواستهای پسزمینه شوند. نتیجه این است که بازدیدکنندههای تازه، حتی برای دیدن یک صفحهی کاملا کششده، باید در صف بمانند؛ چون هیچ Worker آزادی برای رسیدگی به آنها باقی نمانده. این دقیقا همان چیزی است که باعث میشود سایتی که در حالت عادی سریع است، درست در لحظهی اوج ترافیک (مثل یک کمپین فروش) کُند یا حتی از دسترس خارج شود.
گزینهی سادهتر برای کسانی که دسترسی به کدنویسی ندارند
اگر توسعهدهنده در اختیار ندارید، برخی افزونههای کش محبوب مثل WP Rocket و LiteSpeed Cache، بخشی به نام Heartbeat Control دارند که از داخل تنظیمات همان افزونه، بدون نیاز به نوشتن کد، امکان محدودکردن فاصلهی Heartbeat را میدهد. این راهحل بهاندازهی تنظیم دقیق و اختصاصی مؤثر نیست، اما برای شروع و بدون کمک فنی، گزینهی قابل قبولی است. برای Cart Fragments هم افزونههای کوچک و مستقلی وجود دارند که این اسکریپت را فقط زمانی فعال نگه میدارند که سبد خرید کاربر خالی نباشد.
تشخیص از طریق گزارش سرور، بدون نیاز به افزونه
اگر به لاگ دسترسی سرور (Access Log) دسترسی دارید، میتوانید تعداد واقعی درخواستهای admin-ajax.php در طول یک روز را بشمارید. اگر این عدد نسبت به تعداد بازدیدکنندهی واقعی سایت بسیار بالا به نظر برسد، مثلا چند هزار درخواست برای تنها چند صد بازدیدکننده، این خودش نشانهی روشنی از وجود همین مشکل است، پیش از آنکه حتی نیاز به بررسی دقیقتر باشد.
تشخیص این مشکل نیازمند بررسی مستقیم درخواستهای سرور و رفتار واقعی افزونههاست، نه تنظیم یک افزونهی کش. وبکاستر این نوع بررسی و اصلاح را بخشی از بهینهسازی کد و ارتقای عملکرد سایت انجام میدهد. برای مروری کلیتر بر تفاوت این خدمت با بهینهسازی سطحی سرعت، میتوانید این راهنما را هم ببینید.سوالات متداول
بله، برای پروفایلینگ دقیق و اعمال تغییرات، دسترسی فنی به هاست و کد سایت لازم است.
با مقایسه معیارهای مشخص فنی (زمان پاسخ سرور، تعداد کوئریها، مصرف منابع) قبل و بعد از بهینهسازی.
اگر زمان پاسخ اولیهی سرور حتی با کش فعال بالا بماند، یا سرعت با هر آپدیت افزونه نوسان کند، احتمال مشکل در سطح کد بیشتر از هاست است.
تعویض هاست میتواند منابع سختافزاری بیشتری در اختیار سایت بگذارد، اما کوئری کند یا کد ناکارآمد را اصلاح نمیکند؛ این مشکلات با تعویض هاست دوباره ظاهر میشوند.
روشی برای ذخیرهی موقت نتیجهی یک محاسبه یا کوئری پرهزینه تا در درخواستهای بعدی، بهجای تکرار کامل آن محاسبه، همان نتیجهی ذخیرهشده بازخوانی شود.
خیر؛ از نسخهی ۷.۸ ووکامرس، اسکریپت Cart Fragments دیگر بهطور پیشفرض در همهی صفحات اجرا نمیشود. این مشکل بیشتر در فروشگاههای با نسخهی قدیمیتر یا قالبهای کلاسیک دیده میشود.
غیرفعال کردن کامل آن ممکن است روی ذخیرهی خودکار نوشته یا هشدار تداخل بین دو ویرایشگر اثر بگذارد؛ افزایش فاصلهی زمانی، معمولا گزینهی امنتری نسبت به غیرفعالکردن کامل است.
اگر سایت شما در تستهای سرعت آنلاین نمرهی خوبی میگیرد اما زیر بار ترافیک واقعی کُند یا ناپایدار میشود، این یکی از محتملترین دلایل است؛ بررسی دقیق آن نیازمند ابزارهای فنی مثل Query Monitor است.


