Heartbeat API של WordPress: למה הוא מאיט את האדמין ואיך מאיטים אותו נכון

Heartbeat שולח admin-ajax כל 15-60 שניות מכל לשונית פתוחה. כך מאיטים בלי לשבור autosave.

Heartbeat API נכנס ל-WordPress 3.6 (2013) כדי לאפשר תקשורת בזמן-אמת בין דפדפן לשרת: autosave, נעילת פוסטים מפני עריכה מקבילה, התראות חדשות בדשבורד. הוא שולח בקשת POST ל-admin-ajax.php בתדירות של 15 שניות בעורך פוסטים ו-60 שניות בשאר עמודי האדמין. ב-frontend הוא לא רץ בכלל. הבעיה: כל לשונית WP-Admin פתוחה שולחת את הבקשה הזו ללא הרף, גם אם המשתמש בכלל לא ממקודל בלשונית.

למה זה משנה

החישוב פשוט: 4 לשוניות wp-admin פתוחות אצל אדמין יחיד = 4 בקשות בכל 60 שניות = 240 בקשות לשעה לשרת. כל בקשה כזו טוענת את WordPress המלא - bootstrap מלא, $alloptions, hooks, חיבור MySQL. ב-VPS קטן (1 vCPU, 1GB RAM) זה יכול להיות 30-50% מעומס ה-CPU. באתר עם 5 עורכי תוכן שעובדים במקביל, השרת מתחיל לעוט.

בקשת heartbeat תמימה היא לרוב 200-500ms של עבודת PHP. אם יש בקשה איטית באתר (אוטוטעינה כבדה, מסד נתונים איטי), היא יכולה להגיע ל-2-3 שניות. כל בקשה כזו לא רק מבזבזת CPU - היא תופסת PHP-FPM worker. כש-php-fpm.max_children הוא 10 ויש 8 עובדים תופסים heartbeat, רק 2 נשארים לגולשים אמיתיים.

איך לזהות

פתח עמוד אדמין כלשהו. F12 > Network > סנן XHR. תוך 60 שניות צריכה להופיע בקשת POST ל-admin-ajax.php?action=heartbeat. אם הצליחה - Heartbeat פעיל. בדוק גם בעמוד עריכת פוסט: שם זה כל 15 שניות.

בדיקה משלימה: התקן Query Monitor. בכל בקשת heartbeat הוא ירשום את משך הזמן, מספר השאילתות, ובאיזה הוקים מעורבים. אם רואים heartbeat שלוקח יותר מ-300ms - יש שיפור משמעותי לעשות.

איך לתקן

הפתרון הסטנדרטי: תוסף Heartbeat Control של WordPress.org (חינמי, של LittleBizzy):

  1. התקן והפעל
  2. הגדרות > Heartbeat Control
  3. Frontend: "Disable Heartbeat" - אין סיבה שירוץ ב-frontend בכלל
  4. WordPress Dashboard: "Disable Heartbeat" - או "Modify" עם interval של 120 שניות אם משתמשים ב-notifications חיים
  5. WordPress Post Editor: "Allow Heartbeat" עם interval של 60 שניות (לא פחות, אחרת autosave לא יעבוד)

חלופה ידנית ב-functions.php של תבנית ילד:

// כיבוי heartbeat ב-frontend
add_action('init', function () {
    if (!is_admin()) {
        wp_deregister_script('heartbeat');
    }
});

// האטה ב-dashboard ל-120 שניות
add_filter('heartbeat_settings', function ($settings) {
    $settings['interval'] = 120;
    return $settings;
});

אם רוצים לכבות לחלוטין גם ב-admin (לא מומלץ אם משתמשים ב-Gutenberg עם autosave):

add_action('admin_enqueue_scripts', function () {
    wp_deregister_script('heartbeat');
});

טעויות נפוצות

הטעות החמורה ביותר: לכבות heartbeat גם בעורך הפוסטים. אז autosave מפסיק לעבוד, ועריכה מקבילה של שני עורכים לא מזוהה (מתפרסם רק האחרון ששמר). שמור על interval של 60 שניות בעורך, גם אם רוצים לחסוך CPU. הטעות השנייה: לכבות frontend אבל לשכוח dashboard - שם זה הצרכן הגדול. הטעות השלישית: להגדיר interval גבוה מאוד (300+ שניות) - WordPress לא תמיד מכבד ערכים מעבר לטווח 15-120, ייתכן שזה ייצור התנהגות לא צפויה.

בדיקה לאחר תיקון

פתח דשבורד אדמין, F12 > Network > XHR, וחכה דקה. אסור לראות בקשת admin-ajax עם action=heartbeat (אם כיבית) או שהיא צריכה לרוץ פעם ב-120 שניות (אם האטת). בעורך פוסט - חכה 60 שניות וודא שיש בקשה אחת. הקלד טקסט בעורך, חכה דקה, ותוכל לסגור את הלשונית - בכניסה חוזרת WP אמור להציע לשחזר. אם לא - autosave נשבר ואתה שמת interval גבוה מדי.

למדידת CPU: ב-cPanel תחת "Resource Usage" השווה את העומס לפני ואחרי. שיפור של 10-30% בעומס CPU בשעות ערב (כשהאדמין פתוח) הוא תוצאה ריאלית.

טיפ: אם אתר WooCommerce שלך מציג "New order" notifications בזמן אמת בדשבורד, אל תכבה heartbeat לחלוטין שם. הגדר 60 שניות - זה מספיק להתראות וחוסך לפחות 75% מהבקשות.