واتسابدمشقالسبت – الخميس·10:00 ص – 7:00 م

لماذا يبطؤ موقع ووردبريس، وكيف تشخّص السبب فعلياً

زمن أول بايت يفصل مشكلة الخادم عن مشكلة المتصفح. من هذا الرقم تبدأ، ثم تلاحق الاستعلامات وجدول الخيارات قبل أن تفكّر في ذاكرة مؤقتة.

الأداءنُشر في 4 دقائق قراءة

ابدأ بالقياس، لا بالتخمين

"الموقع بطيء" ليست تشخيصاً، بل شكوى. أول ما يجب أن تعرفه هو أين يضيع الوقت: قبل وصول أول بايت من الخادم، أم بعده في المتصفح. القياسان مختلفان تماماً، وعلاجهما مختلف تماماً، وأكثر ما يُهدر من وقت في تسريع المواقع يُهدر في علاج الطرف الخطأ.

curl -o /dev/null -s -w 'dns:%{time_namelookup} connect:%{time_connect} ttfb:%{time_starttransfer} total:%{time_total}\n' https://example.com/

الرقم الذي يهمّك هنا هو time_starttransfer، أي زمن أول بايت. إذا كان تحت 300 ميلي ثانية فمشكلتك في الواجهة الأمامية: صور ثقيلة، ملفات CSS تحجب العرض، خطوط تُحمَّل من نطاق ثالث. وإذا كان ثانية أو أكثر فالمشكلة داخل PHP وقاعدة البيانات، ولن يصلحها ضغط الصور مهما بالغت فيه.

كرّر القياس على صفحة رئيسية، وصفحة مقال، وصفحة أرشيف، ومرّة وأنت مسجّل الدخول. الفرق بين هذه الأربعة يقول لك الكثير: ذاكرة الصفحات تخدم الزائر المجهول ولا تخدم المستخدم المسجّل، فإذا كانت الصفحة سريعة للزائر وبطيئة لك فأنت تنظر إلى زمن التوليد الحقيقي، غير مغطّى بذاكرة مؤقتة.

اجعل الخادم يشرح نفسه

ثبّت Query Monitor على نسخة تطوير أو فعّله لمستخدم مدير واحد فقط. هو الأداة الوحيدة التي تربط استعلاماً بطيئاً بالإضافة التي أطلقته، وهذه الرابطة هي كل التشخيص. ما تبحث عنه ثلاثة أرقام: عدد الاستعلامات، وزمنها الكلي، وأبطأ استعلام مفرد. صفحة سليمة في ووردبريس تنجز عملها في عشرات قليلة من الاستعلامات. إذا رأيت 400 استعلاماً في صفحة واحدة فأنت أمام إضافة تستدعي get_post_meta داخل حلقة دون تحميل مسبق.

المشتبه بهم المعتادون

جدول wp_options المتضخّم. كل طلب صفحة يحمّل صفوف autoload كاملة قبل أن يبدأ أي عمل مفيد:

sql
SELECT SUM(LENGTH(option_value)) AS bytes
FROM wp_options WHERE autoload IN ('yes','on');

النتيجة الصحية أقل من مئة كيلوبايت. رأيت مواقع تحمّل ثمانية ميغابايت في كل طلب لأن إضافة قديمة كتبت سجلّاتها في خيار تلقائي التحميل. اعرف أكبر الصفوف بالاسم قبل أن تحذف شيئاً، وافحص أيضاً حجم العوابر المنتهية (transients):

sql
SELECT option_name, LENGTH(option_value) AS bytes
FROM wp_options WHERE autoload IN ('yes','on')
ORDER BY bytes DESC LIMIT 20;

استعلامات meta_query. جدول wp_postmeta مفهرس على meta_key لا على meta_value. أي فرز أو ترشيح على القيمة يعني مسحاً كاملاً للجدول، ويزداد سوءاً خطّياً مع نمو المحتوى. متاجر ووكومرس تصطدم بهذا أولاً. الحل ليس فهرساً جديداً في الغالب، بل نقل الحقل الذي تُرشّح عليه إلى تصنيف (taxonomy) أو جدول خاص.

wp-cron على كل طلب. ووردبريس افتراضياً يفحص مهامه المجدولة في كل زيارة، ومهمة ثقيلة واحدة تعني أن زائراً عشوائياً هو من يدفع ثمنها. عطّله واستبدله بمهمة نظام حقيقية:

php
// wp-config.php
define('DISABLE_WP_CRON', true);
*/5 * * * * cd /home/user/public_html && wp cron event run --due-now

admin-ajax.php ونبض لوحة التحكم. إذا كانت لوحة التحكم وحدها هي البطيئة، افتح تبويب الشبكة وانظر إلى الطلبات المتكرّرة. إضافات كثيرة تستطلع الخادم كل خمس عشرة ثانية بلا سبب.

طلبات HTTP خارجية داخل مسار الطلب. إضافة تتحقق من ترخيصها، أو تجلب تغريدات، أو تسأل خادم إعلانات — وكل ذلك يحدث بين ضغطة الزائر وظهور الصفحة. Query Monitor يعرض هذه الطلبات في تبويب مستقل. أي طلب خارجي متزامن هو نقطة فشل ومصدر تأخير في آن.

ثم، ومتأخراً، ركّب ذاكرة مؤقتة

الترتيب مقصود. الذاكرة المؤقتة تخفي المشكلة ولا تحلّها، وموقع بطيء مع ذاكرة يبقى بطيئاً لأول زائر بعد كل تحديث، ولكل مستخدم مسجّل، ولكل صفحة لم تُسخَّن بعد. بعد أن تُصلح ما سبق، ركّبها بهذا الترتيب:

  1. OPcache — تجميع PHP مرة واحدة بدل كل طلب. الأثر كبير والكلفة صفر.
  2. ذاكرة كائنات مستمرّة (Redis أو Memcached حيث تتوفّر، وإلا APCu). تنفع الموقع الديناميكي والمستخدم المسجّل.
  3. ذاكرة صفحات — تخدم HTML جاهزاً للزائر المجهول. هذه أكبر مكسب منفرد لموقع محتوى، وأقلّها نفعاً لمتجر أو لوحة تحكم.

قياس النهاية

أعد قياس curl نفسه بعد كل تغيير، لا بعدها كلها. تغيير لا يتحرّك معه الرقم هو تغيير لم تكن تحتاجه، وأنت الآن تعرف ذلك بدل أن تظنّه. واحذر من اختبار الحمل على استضافة مشتركة: أدوات مثل ab وhey تُشبِع نواة المعالج المخصّصة لحسابك، فتقيس حدّ الحساب لا سرعة الموقع، وتزعج جيرانك على الخادم بلا فائدة.

لماذا يبطؤ موقع ووردبريس، وكيف تشخّص السبب فعلياً · Qasioun Cloud