مشكلة الأداء
إذا سبق لك أن رأيت صفحة جوال تُحمّل "بسرعة" ثم تقفز لمدة ثانيتين، فمن المحتمل أن يكون لديك مزيج سام: صور كبيرة جدًا + تستجيب الصور تم تكوينها بشكل غير صحيح + أبعاد مفقودة. تشغيل WordPress 6.9.4، القلب يعرف كيف يولد srcset et sizesلكن كل ما يتطلبه الأمر هو قالب أو أداة بناء أو جزء "تحسين" عدواني قليلاً لكسر السلسلة.
العرض الملموس: انخفاض متوسط درجة الحركة، وهيمنة صورة "بطلة" على أكبر عنصر محتوى (LCP)، وتحول التخطيط التراكمي (CLS) الناتج عن صور بدون width/heightوعمليات النقل غير الضرورية (مثل إرسال صورة بحجم 2000 بكسل إلى شاشة بحجم 390 بكسل). لقد واجهت هذا الأمر مرارًا وتكرارًا في مواقع Elementor/Avada حيث تقوم أداة ما بإضافة كود HTML خاص بالصورة وتعطيل خصائصها. WordPress.
في النهاية، ستعرف:
- تشخيص دقيق للصور التي تبطئ الجهاز المحمول (وسبب ذلك) باستخدام التعليمات البرمجية؛
- دع ووردبريس 6.9.4 يُنشئ
srcsetصحّح (أو صحّحه بشكل صحيح)؛ - اضبط
sizesحسب السياق (المحتوى، الأعمدة، أدوات الإنشاء)؛ - تحسين LCP دون "تعطيل الكسل" في أي مكان.
ملخص سريع
- لا تقم بإنشاء
<img>باليد: استخدمwp_get_attachment_image()outhe_post_thumbnail()للحصول علىsrcset,sizesوالأبعاد. - صحيح
sizesحسب السياق (المحتوى مقابل الشريط الجانبي مقابل الشبكة) عبر الفلترwp_calculate_image_sizes. - معالجة صورة LCP:
fetchpriority="high"التحميل المسبق المستهدف، وقبل كل شيء حجم مناسب تمامًا لشاشة عرض الهاتف المحمول. - لا تقم "بتعطيل" التحميل الكسول بشكل عام: تجنبه فقط على صورة LCP وعلى بعض أشرطة التمرير.
- قم بتمكين WebP/AVIF على كل من جانب الإنشاء وجانب الخادم، ولكن احذر من الإضافات التي تستبدل عناوين URL وتقطع الاتصال.
srcset.
رمز التشخيص
1) تفعيل وضع تصحيح الأخطاء القابل للاستخدام (دون إحداث أي خلل)
تجنب في موقع الإنتاج WP_DEBUG_DISPLAYقم بتسجيل الدخول، ثم قم بالتحليل.
<?php
// wp-config.php (WordPress 6.9.4+, PHP 8.1+)
// Active le debug
define('WP_DEBUG', true);
// Log dans wp-content/debug.log
define('WP_DEBUG_LOG', true);
// Ne pas afficher aux visiteurs
define('WP_DEBUG_DISPLAY', false);
// Optionnel : utile si vous traquez un plugin qui spamme des notices
@ini_set('display_errors', '0');
2) ببساطة قم بقياس حجم الصورة ووجود srcset/sizes
المتصفح هو مصدر الحقيقة، ولكن يمكنك بالفعل اكتشاف الصفحات "المشبوهة" من جانب PHP: صور بدون srcsetدون sizesأو بدون أبعاد. يقوم هذا الملحق (mu-plugin) بتسجيل ملخص لكل طلب (تجنب تركه نشطًا بشكل دائم).
<?php
/**
* Plugin Name: Perf Mobile - Audit Images (mu-plugin)
* Description: Log des indicateurs simples sur les <img> rendues (srcset/sizes/dimensions).
*/
add_action('template_redirect', function () {
if (is_admin() || wp_doing_ajax() || wp_is_json_request()) {
return;
}
ob_start(function ($html) {
// Analyse naïve mais utile : on cherche les <img ...>
if (!preg_match_all('/<imgb[^>]*>/i', $html, $matches)) {
return $html;
}
$total = count($matches[0]);
$missing_srcset = 0;
$missing_sizes = 0;
$missing_dims = 0;
foreach ($matches[0] as $img) {
if (stripos($img, 'srcset=') === false) {
$missing_srcset++;
}
if (stripos($img, 'sizes=') === false) {
$missing_sizes++;
}
$has_w = preg_match('/bwidth=("|')?d+/i', $img);
$has_h = preg_match('/bheight=("|')?d+/i', $img);
if (!$has_w || !$has_h) {
$missing_dims++;
}
}
error_log(sprintf(
'[perf-images] %s | imgs=%d | no-srcset=%d | no-sizes=%d | no-dims=%d',
wp_get_raw_referer() ?: (is_singular() ? get_permalink() : home_url(add_query_arg([]))),
$total,
$missing_srcset,
$missing_sizes,
$missing_dims
));
return $html;
});
}, 0);
بحسب تجربتي، إذا رأيت الكثير من no-srcset في الصفحات التي تتوقع فيها صور "ووردبريس" (الصورة المميزة، صور المحتوى)، يكون الأمر دائمًا تقريبًا عبارة عن أداة إنشاء أو إضافة تحسين تقوم بإعادة كتابة HTML.
3) مراقبة الاستعلامات + تحديد الاستعلامات البطيئة المتعلقة بالوسائط
بالنسبة لبرنامج مراقبة الاستعلامات، سأترك عملية التثبيت لك: مراقبة الاستعلامات (wordpress.org)أما فيما يتعلق بالبرمجة، فإن أكثر ما يهمك فيما يخص الصور هو:
- الطلبات
postmetaالتي تنفجر (موضوع يسترجع 20 حجم صورة واحدًا تلو الآخر)؛ - اتصالات متكررة بـ
wp_get_attachment_metadata()ouimage_downsize()في حلقة مفرغة.
إذا كنت ترغب في الحصول على إشارة بدون واجهة مستخدم، فقم بتمكين تسجيل استعلامات MySQL البطيئة (إذا كان لديك صلاحية الوصول إلى الخادم). غالبًا ما يكون هذا مفيدًا في صفحات "شبكة المقالات" التي تحتوي على صور مصغرة.
4) WP-CLI: تحقق من الأحجام المتاحة وأعد إنشاءها إذا لزم الأمر
عندما srcset إذا كان الوضع سيئًا، فقد يكون السبب بسيطًا: عدم إنشاء أحجام وسيطة، أو تغيير في الحجم بعد الاستيراد. باستخدام WP-CLI:
# Liste des tailles déclarées (thème + plugins)
wp eval 'print_r( wp_get_registered_image_subsizes() );'
# Vérifie la version WP / PHP
wp core version
php -v
لإعادة إنشاء الصور، ستستخدم عادةً إضافةً (مثل "إعادة إنشاء الصور المصغرة"). لن أدرج هنا أي أوامر "سحرية" لأنه، اعتمادًا على بيئة العمل لديك، قد تُسبب إعادة إنشاء 50 ألف صورة في بيئة الإنتاج دون استراتيجية مُحكمة مشاكل.
الخطوة 1: تنظيف كود HTML للسماح لـ WordPress بإنشاء srcset/sizes
ما الذي يبطئها (قبل)
نمط مضاد كلاسيكي: ترميز HTML للصور يدويًا، بدون srcsetدون sizesأحيانًا بدون أبعاد. على الهاتف المحمول، أنت تعرض صورة كبيرة جدًا، ولا يستطيع المتصفح اختيار الحجم المناسب.
<?php
// Template.php (lent / fragile)
$img_url = get_post_meta(get_the_ID(), 'hero_image_url', true);
echo '<img src="' . esc_url($img_url) . '" alt="" class="hero">';
// Pas de srcset, pas de sizes, pas de width/height => LCP + CLS + octets inutiles
وهذا يتسارع (بعد ذلك)
قم بتخزين مُعرّف المرفق، وليس عنوان URL. ثم دع ووردبريس يُنشئ الترميز عبر wp_get_attachment_image()يستخدم النظام الأساسي البيانات الوصفية (الأحجام المُولَّدة) لإنتاج srcset, sizes et width/height.
<?php
// Template.php (optimisé / WordPress-native)
$hero_id = (int) get_post_meta(get_the_ID(), 'hero_image_id', true);
if ($hero_id) {
echo wp_get_attachment_image(
$hero_id,
'large', // Taille logique (sera adaptée via srcset)
false,
[
'class' => 'hero',
'alt' => get_post_meta($hero_id, '_wp_attachment_image_alt', true) ?: get_the_title(),
]
);
}
قياس الأثر (بسيط وواقعي)
لا يُعدّ قياس "التحسين" على مستوى لغة PHP ذا جدوى كبيرة هنا، فالتحسين الحقيقي يكمن في الشبكة بالإضافة إلى عملية العرض. مع ذلك، يمكنك مراقبة وقت إنشاء الترميز إذا كنت تشك في أن أحد القوالب يقوم بعمليات معالجة كثيفة الاستخدام للموارد.
<?php
// Petit chronométrage (log) autour d'un rendu d'image
$start = hrtime(true);
$html = wp_get_attachment_image($hero_id, 'large', false, ['class' => 'hero']);
$ms = (hrtime(true) - $start) / 1e6;
error_log(sprintf('[perf] wp_get_attachment_image hero: %.2f ms', $ms));
echo $html;
من الناحية العملية، يأتي التحسن الأكثر وضوحًا بشكل أساسي من حقيقة أن المتصفح يختار موردًا أصغر عبر srcsetفي موقع مدونة، رأيت بالفعل صفحات تنتقل من 1.4 ميجابايت من الصور المنقولة إلى 450 كيلوبايت على الهاتف المحمول بمجرد إزالة كود HTML للصور "المُعدّ منزليًا".
التوافق مع Divi 5 / Elementor / Avada
- Elementor قد تُخرج بعض أدوات "الصور" ترميزًا صحيحًا، ولكن بمجرد استخدام الحقول الديناميكية (ACF/Meta) أو الإضافات، ستعود إلى عنوان URL بسيط. يُفضّل استخدام حقل يُعيد مُعرّفًا، أو العرض عبر رمز مختصر مُخصّص يستدعي
wp_get_attachment_image(). - ديفي 5 نفس المنطق. الوحدة النمطية المخصصة (أو الرمز المختصر) التي تستقبل مُعرّف المرفق أكثر موثوقية من عنوان URL.
- فتح احذر من خيارات "التحميل الكسول" و"تحسين الصور" في القالب، لأنها تُعيد كتابة كود HTML. جرّب تعطيل هذه الخيارات مؤقتًا للتأكد من عدم حدوث أي تغيير.
srcsetيعود.
الخطوة الثانية: تحديد الحجم الذكي حسب السياق وحسب نقاط التوقف
المشكلة: مجموعة المصادر موجودة، لكن الأحجام غير صحيحة
غالبًا ما يقوم ووردبريس بإنشاء sizes عام، يعتمد على أقصى عرض للمحتوى. في صفحة تحتوي على شريط جانبي أو شبكة أو أداة إنشاء وحدات قائمة على الأعمدة، هذا sizes قد يكون عريضًا جدًا. النتيجة: يختار المتصفح مصدرًا أكبر من اللازم.
ألاحظ هذا غالبًا في صفحات "المدونة" ذات الأعمدة الثلاثة: يبلغ عرض كل بطاقة حوالي 320 بكسل على الهاتف المحمول، ولكن sizes يعرض الإعلان صورة بحجم 768 بكسل. لذلك يقوم المتصفح بتنزيل صورة بحجم 768 عرض.
الحل: تصفية wp_calculate_image_sizes حسب السياق
مرشح wp_calculate_image_sizes يتيح لك ضبط السلسلة sizes محسوب. سنقوم بما يلي:
- الصور المستهدفة من المحتوى (الفئة)
wp-image-)؛ - في الأرشيفات/الشبكات، أعلن عن عرض أصغر؛
- في الشريط الجانبي، اعرض إعلانات أصغر حجماً.
<?php
/**
* Ajuste l'attribut sizes pour éviter de sur-télécharger des images sur mobile.
* Testé sur WordPress 6.9.4+.
*/
add_filter('wp_calculate_image_sizes', function ($sizes, $size, $image_src, $image_meta, $attachment_id) {
// Ne touchez pas à l'admin ni aux requêtes API
if (is_admin() || wp_is_json_request()) {
return $sizes;
}
// $size peut être [width, height] ou un nom de taille selon le contexte
$requested_width = is_array($size) ? (int) $size[0] : 0;
// Cas 1 : thumbnails en archive (grilles d'articles)
if (is_home() || is_archive() || is_search()) {
// Hypothèse réaliste : grille 2 colonnes sur mobile, 3 sur tablette+
// Ajustez selon votre CSS réel (sinon vous "mentez" au navigateur).
return '(max-width: 480px) 48vw, (max-width: 1024px) 30vw, 320px';
}
// Cas 2 : images dans une sidebar (si votre thème ajoute une classe dédiée)
// Exemple : widgets qui enveloppent les images dans .sidebar
if (is_active_sidebar('sidebar-1')) {
// Sizings conservateurs pour une colonne étroite
return '(max-width: 480px) 92vw, 300px';
}
// Cas 3 : fallback - gardez le comportement WP
return $sizes;
}, 10, 5);
لماذا هو أسرع؟
srcset تتوفر بأحجام مختلفة. sizes يشرح للمتصفح العرض réelle يتم العرض وفقًا لحجم نافذة العرض. إذا sizes الصورة كبيرة جدًا؛ المتصفح يختار صورة كبيرة جدًا. صحح هذا الخطأ. sizes يقلل من عدد البايتات المنقولة ويسرع عملية فك التشفير/العرض (غالباً ما يكون ذلك واضحاً على LCP ووقت وحدة المعالجة المركزية للأجهزة المحمولة).
حالات الحافة
- إذا تغيرت خصائص CSS الخاصة بك بناءً على حاوية (منشئ التخطيط)،
vwقد يكون ذلك مضللاً. قم بقياس العرض الفعلي. - لا تضع
sizes"صغير جدًا": ستجبر المتصفح على اختيار صورة ذات دقة منخفضة جدًا (ضبابية على الشاشات الكثيفة). - إذا كان لديك شبكة توصيل محتوى (CDN) تقوم "بتوحيد" عناوين URL (مثل المعلمات)، فتأكد من أن جميع الإدخالات في
srcsetأشر إلى عناوين URL صالحة.
الخطوة 3: تجنب الصور "الرئيسية" الكبيرة جدًا (التحميل المسبق، والأولوية، وLCP)
الفخ الكلاسيكي
أنت تُفعّل خاصية التحميل الكسول في كل مكان. ونتيجةً لذلك، يتم تحميل الصورة الرئيسية (والتي غالبًا ما تكون عنصر LCP) متأخرًا لأنها تنتظر تقاطع المُراقب. ينخفض مستوى LCP، على الرغم من تحميل عدد أقل من الصور في البداية.
1) تعطيل التحميل الكسول فقط على صورة LCP
ووردبريس يضيف loading="lazy" على العديد من الصور. الفلتر wp_lazy_loading_enabled يُتيح ذلك التحكم. هنا، نقوم بتعطيل العرض الكسول للصورة الأولى من المحتوى في الصفحات الفردية، وللصورة المميزة إذا تم عرضها عبر the_post_thumbnail() (حالة متكررة).
<?php
/**
* Désactive le lazy-loading pour l'image la plus critique (souvent LCP).
* Approche pragmatique : première image "importante" sur singular.
*/
add_filter('wp_lazy_loading_enabled', function ($default, $tag_name, $context) {
if ($tag_name !== 'img') {
return $default;
}
if (!is_singular()) {
return $default;
}
// Contexte "the_content" et "wp_get_attachment_image" sont fréquents.
// On ne peut pas identifier "la" LCP de façon parfaite côté PHP sans heuristiques.
static $already_disabled_once = false;
if (!$already_disabled_once && in_array($context, ['the_content', 'wp_get_attachment_image', 'post_thumbnail'], true)) {
$already_disabled_once = true;
return false; // Pas de lazy pour la première occurrence
}
return $default;
}, 10, 3);
2) أضف fetchpriority=high إلى الصورة الحرجة
تستخدم المتصفحات الحديثة fetchpriorityيُمكن لـ WordPress بالفعل إدارة خصائص الصور عبر الفلاتر. هنا، نضيف fetchpriority="high" في صورة مميزة على المفرد إذا كان في أعلى الصفحة (استدلالي).
<?php
/**
* Ajoute fetchpriority=high sur la miniature mise en avant en haut de page.
* Attention : ne le faites pas sur 10 images, sinon vous cassez la priorisation.
*/
add_filter('wp_get_attachment_image_attributes', function ($attr, $attachment, $size) {
if (!is_singular()) {
return $attr;
}
// On cible uniquement l'image mise en avant si le thème utilise post-thumbnail
// Heuristique : classe "wp-post-image" ajoutée par the_post_thumbnail()
$class = isset($attr['class']) ? (string) $attr['class'] : '';
if (str_contains($class, 'wp-post-image')) {
$attr['fetchpriority'] = 'high';
// Bonus : si vous voyez des CLS, assurez-vous que width/height existent
}
return $attr;
}, 10, 3);
3) التحميل المسبق الموجه (دون الوقوع في فخ التحميل المسبق "في كل مكان")
قد يساعد تحميل صورة LCP مسبقًا، ولكن فقط إذا قمت بتحميلها مسبقًا خيار جيدتحميل عنوان URL "كبير الحجم" على الهاتف المحمول مسبقًا هو نمط سيء: فأنت تجبر على تنزيل مورد كبير جدًا.
الحل الأمثل: تحميل الصورة الرئيسية مسبقًا باستخدام المصدر الأنسب للهواتف المحمولة (مثلاً، 768w). سنحصل على رابط URL متوسط الحجم، وليس الرابط الأصلي.
<?php
/**
* Preload raisonnable de l'image mise en avant en taille intermédiaire.
* À adapter à votre design : choisissez une taille réellement utilisée au-dessus de la ligne de flottaison.
*/
add_action('wp_head', function () {
if (!is_singular() || !has_post_thumbnail()) {
return;
}
$thumb_id = get_post_thumbnail_id();
if (!$thumb_id) {
return;
}
// Choisissez une taille existante. 'medium_large' est souvent pertinente pour mobile.
$src = wp_get_attachment_image_src($thumb_id, 'medium_large');
if (!$src || empty($src[0])) {
return;
}
$href = esc_url($src[0]);
echo '<link rel="preload" as="image" href="' . $href . '">' . "n";
}, 1);
ملاحظة: إذا كان موقعك يستخدم إضافة صور تُنشئ نسخًا مختلفة تلقائيًا (شبكة توصيل المحتوى مع معلمات)، فقد يكون هذا الأسلوب غير مُجدٍ. في هذه الحالة، من الأفضل ترك المتصفح يختار عبر srcset والتركيز على sizes et fetchpriority.
الخطوة الرابعة: جودة WebP/AVIF و JPEG دون التأثير على مجموعة المصادر
هدف
على الأجهزة المحمولة، غالبًا ما يكون تقليل حجم البيانات أكثر فعالية من حيث التكلفة من "التحسين الدقيق" لطلب PHP. يُحدث استخدام WebP/AVIF مع الضغط المناسب فرقًا فوريًا، شريطة ألا تكون عناوين URL معطوبة. srcset.
1) اضبط جودة الضغط (JPEG/WebP) على جانب ووردبريس
يوفر ووردبريس فلاتر لتحسين الجودة. لا تزال العديد من المواقع تستخدم جزءًا قديمًا من التعليمات البرمجية التي تفرض 100 "من أجل الجودة"، وهي كارثة على الهواتف المحمولة.
<?php
/**
* Qualité d'images : compromis réaliste pour blog.
* Attention : baisser trop peut dégrader les visuels (banding).
*/
add_filter('jpeg_quality', function ($quality) {
return 82;
});
add_filter('wp_editor_set_quality', function ($quality, $mime_type) {
// MIME types possibles : image/jpeg, image/webp, image/avif...
return match ($mime_type) {
'image/jpeg' => 82,
'image/webp' => 80,
'image/avif' => 45,
default => $quality,
};
}, 10, 2);
2) تحقق من وجود أحجامك بالفعل (وإلا فإن srcset غير كافٍ)
إذا كان قالبك يحفظ مقاسين فقط، فـ srcset ستكون محدودة. أضف أحجامًا وسيطة تتوافق مع نقاط التوقف الخاصة بك (دون إنشاء 25 منها: فهذا يزيد من أوقات التخزين والتجديد).
<?php
/**
* Déclare quelques tailles utiles pour mobile/tablette.
* À placer dans functions.php d'un thème enfant ou dans un plugin.
*/
add_action('after_setup_theme', function () {
add_image_size('card_360', 360, 0, false); // Cartes mobile
add_image_size('card_540', 540, 0, false); // Cartes mobile dense / tablette
add_image_size('hero_960', 960, 0, false); // Hero mobile/tablette
});
3) استخدم هذه المقاسات في قوالبك (وإلا ستكون عديمة الفائدة)
<?php
// Exemple : grille d'articles (archive)
if (has_post_thumbnail()) {
echo get_the_post_thumbnail(
get_the_ID(),
'card_360',
[
'class' => 'archive-card-thumb',
'alt' => the_title_attribute(['echo' => false]),
]
);
}
توافق إضافة تحسين الصور
العديد من الإضافات/شبكات توصيل المحتوى (CDN) تستبدل src عبر عنوان URL للوكيل ومحاولة إعادة البناء srcsetهذا هو المكان الذي ترى فيه... srcset عدم الاتساق (عرض غير صحيح، عناوين URL خاطئة، أو جميع المدخلات متطابقة). عند الاشتباه في ذلك، قم بتعطيل الإضافة مؤقتًا وقارن كود HTML.
إذا كنت مضطرًا لإعادة كتابة عناوين URL، فافعل ذلك عبر مرشحات WordPress على الكود المصدري (واختبره). srcset (مكتملة)، وليس عبر str_replace على مخزن HTML المؤقت.
الخطوة 5: التحميل الكسول دون إضعاف LCP (والدوارات)
المشكلة: أشرطة التمرير والصور "الظاهرة أعلى الصفحة"
في Divi/Elementor/Avada، غالبًا ما يتم عرض الشرائح الدوارة وأقسام البطل باستخدام جافا سكريبت. إذا تم تطبيق التحميل الكسول في المكان الخطأ، فستحصل على:
- صورة LCP متأخرة (الصورة مرئية ولكن لم يتم تحميلها)؛
- ومضة (عنصر نائب)؛
- CLS إذا لم تكن الأبعاد ثابتة.
1) أبعاد القوة (لتجنب CLS)
عادةً ما يضيف ووردبريس width/height إذا كنت تستخدم وظائف أصلية. إذا كان برنامج البناء الخاص بك يقوم بحقن <img> بدون الأبعاد، يمكنك على الأقل تصحيح بعض الحالات عبر wp_img_tag_add_width_and_height_attr (تصفية) أو عن طريق استبدال العرض برمز مختصر يستدعي wp_get_attachment_image().
مثال على رمز "صورة بواسطة المعرف" المختصر القابل للاستخدام في Elementor/Divi/Avada:
<?php
/**
* Shortcode [img_id id="123" size="card_360" class="x"]
* Objectif : produire un <img> WP natif (srcset/sizes/dimensions).
*/
add_shortcode('img_id', function ($atts) {
$atts = shortcode_atts([
'id' => 0,
'size' => 'medium',
'class' => '',
'alt' => '',
], $atts, 'img_id');
$id = (int) $atts['id'];
if (!$id) {
return '';
}
$alt = $atts['alt'] !== '' ? (string) $atts['alt'] : (get_post_meta($id, '_wp_attachment_image_alt', true) ?: '');
return wp_get_attachment_image(
$id,
sanitize_key($atts['size']),
false,
[
'class' => sanitize_html_class($atts['class']),
'alt' => $alt,
]
);
});
2) لا تقم بتأجيل/عدم تزامن أي نص برمجي للصور
تقوم بعض الإضافات بإضافة نص برمجي مخصص للتحميل الكسول وتمريره عبر deferإذا كان هذا البرنامج النصي مسؤولاً عن الاستبدال data-src en srcقد يؤدي التأجيل إلى تأخير العرض. إذا كان لا بد من التأجيل، فافعل ذلك فقط على البرامج النصية غير الحرجة، واختبر LCP.
<?php
/**
* Exemple : defer uniquement sur un script non critique.
* Ne defer pas un script qui hydrate vos images au-dessus de la ligne de flottaison.
*/
add_filter('script_loader_tag', function ($tag, $handle, $src) {
$non_critical = [
'contact-form-7', // exemple
];
if (in_array($handle, $non_critical, true)) {
return '<script src="' . esc_url($src) . '" defer></script>';
}
return $tag;
}, 10, 3);
تكوين الخادم
ملف .htaccess (أباتشي): ذاكرة تخزين مؤقتة قوية للمتصفح للصور
إذا كانت عناوين URL الخاصة بصورك "مُعَرَّفة" (يضيف ووردبريس لواحق الحجم، وتضيف العديد من شبكات توصيل المحتوى معلمات)، فيمكنك إضافة مخبأ طويل. تحذير: إذا كنت تقدم الصور عبر إضافة تعيد كتابة كل شيء بدون نظام تحكم في الإصدارات، فقد يؤدي التخزين المؤقت الطويل إلى تأخير التحديثات حتى الآن.
# .htaccess (Apache) - à placer dans le bloc approprié, hors règles WordPress
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/avif "access plus 1 year"
</IfModule>
<IfModule mod_headers.c>
<FilesMatch ".(jpe?g|png|webp|avif)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
</IfModule>
php.ini: ذاكرة كافية لإنشاء الأحجام (وإلا فلن يكون هناك مجموعة مصادر غنية)
عندما تفشل عملية الإنشاء (صور كبيرة، AVIF)، ينتهي بك الأمر بأحجام ملفات صغيرة، لذا srcset متوسط. إعداد أدنى واقعي:
; php.ini (valeurs typiques)
memory_limit = 256M
max_execution_time = 120
wp-config.php: تقييد تحرير الصور في بيئة الإنتاج
إذا كان لديك مؤلفون يُراجعون أو يُحررون محتواك باستمرار، فسيقوم ووردبريس بإنشاء نسخ جديدة. هذا أمر طبيعي، ولكن في حال كانت سعة الاستضافة محدودة، فقد يُسبب ذلك تباطؤًا في عمليات الإدخال/الإخراج. يمكنك التحكم في العمليات المعنية، ولكن ليس بالضرورة في الكود نفسه. أما بالنسبة للإعدادات، فركز على الحفاظ على بيئة مستقرة والاحتفاظ بسجلات النظام.
التحقق من النتائج
1) تحقق من الترميز المُعالَج (srcset/sizes/dimensions)
قم بإضافة فحص PHP مؤقتًا على صفحة معينة (لكل رابط)، وقم بتسجيل وجود سمات للصورة المميزة.
<?php
add_action('wp', function () {
if (!is_singular('post')) {
return;
}
if (get_post_field('post_name', get_queried_object_id()) !== 'mon-article-test') {
return;
}
if (!has_post_thumbnail()) {
return;
}
$id = get_post_thumbnail_id();
$html = wp_get_attachment_image($id, 'large', false, ['class' => 'test-thumb']);
error_log('[perf-check] thumb html: ' . $html);
});
2) تحقق من الأصناف التي تم تقديمها بالفعل (بدون لقطة شاشة)
في بيئة اختبار، يمكنك استخدام برنامج نصي صغير من نوع Node أو curl لمقارنة Content-Length من عناوين URL مختلفة لـ srcsetمثال بسيط باستخدام curl (سيتم تعديله):
# Remplacez par une URL d'image réelle (une entrée du srcset)
curl -I "https://example.com/wp-content/uploads/2026/04/image-768x512.webp" | grep -i -E "content-length|content-type|cache-control"
3) المتوقع (المقاييس)
- نظام الإجراءات الجزائية : انخفاض ملحوظ إذا تم تحديد أولوية صورة البطل وحجمها بشكل صحيح.
- CLS ينبغي أن تقترب القيمة من الصفر إذا كانت صورك تحتوي على
width/height(أو نسبة CSS مستقرة). - الوزن المنقول انخفاض حاد على الهاتف المحمول إذا
sizesتم تصحيحها.
إذا لم يتحسن الأداء
1) تحقق من أن الكود الخاص بك يعمل بالفعل
خطأ واقعي: تم لصق المقتطف في الملف الخطأ، أو في إضافة مقتطفات معطلة في بعض الصفحات. أضف سجلًا واضحًا:
<?php
add_action('init', function () {
if (!is_admin()) {
error_log('[perf] snippets images responsive chargés');
}
});
2) تعارض مع التخزين المؤقت/التصغير
مثال كلاسيكي آخر: أنت تقوم بالتعديل sizesمع ذلك، لا تزال ذاكرة التخزين المؤقت للصفحة تعرض صفحات HTML القديمة. قم بمسحها:
- ذاكرة التخزين المؤقت للملحقات (ذاكرة التخزين المؤقت للصفحة)؛
- ذاكرة التخزين المؤقت للخادم (Varnish/NGINX microcache)؛
- ذاكرة التخزين المؤقت لشبكة توصيل المحتوى (CDN)؛
- ذاكرة التخزين المؤقت للمتصفح (أو الاختبار في نافذة خاصة).
3) يقوم أحد المكونات الإضافية بإعادة كتابة كود HTML بعد ووردبريس
إذا كان لديك srcset إذا اختفت المشكلة "بعد حدوثها"، فابحث عن مخزن مؤقت للإخراج. اختبار بسيط: عطّل مؤقتًا إضافات تحسين HTML/JS وقارن الناتج.
4) صور الخلفية في CSS (لا يمكن استخدام srcset)
في العديد من شركات البناء، يكون "البطل" هو background-image. هناك، srcset/sizes هذا غير صحيح. نحتاج إلى التبديل إلى واحد حقيقي. <img> (أو <picture>أو إدارة استعلامات الوسائط في CSS مع خلفيات متعددة. إذا كنت ستعتمد على CSS، فعلى الأقل:
/* Exemple : backgrounds responsives (moins optimal qu'un <img> mais mieux que rien) */
.hero {
background-image: url('/wp-content/uploads/2026/04/hero-540.webp');
}
@media (min-width: 768px) {
.hero {
background-image: url('/wp-content/uploads/2026/04/hero-960.webp');
}
}
@media (min-width: 1200px) {
.hero {
background-image: url('/wp-content/uploads/2026/04/hero-1600.webp');
}
}
الأخطاء الشائعة والمزالق
| عرض | السبب المحتمل | التحقق | الحلول |
|---|---|---|---|
| يقوم الهاتف المحمول بتنزيل صورة ضخمة (على سبيل المثال، 2000 بكسل). | sizes واسع جدًا أو غائب |
افحص كود HTML: sizes يعلن عن عرض غير واقعي |
الفرز حسب السعر wp_calculate_image_sizes وفقًا للتصميم الفعلي |
srcset غائب في كل مكان |
صور مُضمنة في الكود (عنوان URL)، أو إضافة/أداة إنشاء تُنشئ ترميزها الخاص | بحث <img بلا srcset في لغة HTML |
استعمال wp_get_attachment_image() / رمز مختصر قائم على المعرف |
| CLS مرئي (فواصل التخطيط) | صور بدون width/heightأو عناصر نائبة غير مستقرة |
السجلات (التدقيق) + فحص العلامات | عرض ووردبريس الأصلي، أو تحديد نسبة CSS ثابتة |
| يصبح أداء LCP أسوأ بعد "تحسين التحميل الكسول". | تم تطبيق Lazy على صورة LCP | قم بقياس LCP والتحقق منه loading="lazy" على الصورة الرئيسية |
قم بتعطيل خاصية العرض الكسول لأول صورة مهمة عبر wp_lazy_loading_enabled + fetchpriority |
| صور ضبابية على الهاتف المحمول | sizes صغير جدًا (أنت "تكذب" على المتصفح) |
قارن بين عرض CSS الفعلي وقيمة sizes |
يُعدِّل sizes (vw/px) + السماح بأحجام وسيطة |
| حدث خطأ فادح بعد إضافة المقتطف البرمجي | قوس مفقود/فاصلة منقوطة مفقودة، أو تم استدعاء الدالة مبكراً جداً | تشاور wp-content/debug.log |
صحّح الصيغة، وضع الكود في إضافة أو قالب فرعي، واستخدم الخطاف الصحيح. |
| لم يحدث أي تأثير على الرغم من الكود | صفحة التخزين المؤقت/شبكة توصيل المحتوى (CDN) تعرض صفحات HTML القديمة | اختبر ذلك عن طريق تعطيل ذاكرة التخزين المؤقت، أو أضف علامة في HTML | امسح جميع ذاكرات التخزين المؤقت، وعطّل شبكة توصيل المحتوى (CDN)، ثم أعد الاختبار. |
أخطاء أراها كثيراً (والتي تضيع الوقت)
- ألصق فلترًا في
functions.phpمن القالب الرئيسي (ثم يفقده عند التحديث). - استخدام خطاف غير مناسب (على سبيل المثال، تعديل
sizesبواسطةthe_content(مع التعبير النمطي: هش وبطيء). - اختبر على بيئة الإنتاج دون حفظ أو تراجع (مقتطف معطل = شاشة بيضاء).
- الاحتفاظ بمقطع قديم من عام 2018 يفرض جودة JPEG على 100.
نصائح الصيانة
- قم بتثبيت أحجام الصور : قم بتغييرها نادراً، وقم بتوثيقها (وإلا ستكون عمليات التجديد مكلفة).
- راقب البنائين/الإضافات بعد تحديث Divi/Elementor/Avada، تحقق من أن ترميز الصورة لم يتغير.
- تجنب إعادة كتابة HTML العامة (تحسين "تخزين الإخراج المؤقت"): هذا هو المصدر الأول لـ
srcsetمكسور. - احتفظ بمقال بعنوان "صفحة اختبار الأداء". مع صورة رئيسية، وشبكة، وشريط جانبي. إنها بمثابة مؤشر لك بعد كل تحديث.
الموارد
- wp_get_attachment_image() (developer.wordpress.org)
- فلتر wp_calculate_image_sizes (developer.wordpress.org)
- تصفية wp_get_attachment_image_attributes (developer.wordpress.org)
- فلتر wp_lazy_loading_enabled (developer.wordpress.org)
- مراقبة الاستعلامات (wordpress.org)
- نسخة GitHub لتطوير WordPress (github.com/WordPress)
- نظام إدارة موارد ووردبريس الأساسي (core.trac.wordpress.org)
- hrtime() (php.net)
الأسئلة الشائعة
هل يقوم ووردبريس 6.9.4 بإنشاء ملفات srcset و sizes تلقائيًا؟
نعم، إذا قمت بعرض صورك باستخدام الوظائف الأصلية (wp_get_attachment_image(), the_post_thumbnail()(الصور المُدرجة في المحرر). إذا قمت بإدخال عنوان URL في <img> "صنع يدوياً"، تفقد بذلك خاصية الإنتاج الآلي.
لماذا لديّ خاصية srcset ولكن الهاتف المحمول لا يزال يعرض الصورة الكبيرة؟
ل sizes يُخبر المتصفح بعرض شاشة أكبر من العرض الفعلي. ثم يختار المتصفح مصدرًا أعرض من srcsetصحيح sizes بواسطة wp_calculate_image_sizes مع مراعاة خصائص CSS الخاصة بك.
هل يمكنني وضع الأحجام "100vw" في كل مكان؟
يمكنك ذلك، لكنه غالباً ما يكون خاطئاً في الشبكات والأشرطة الجانبية وتخطيطات الأعمدة. 100vw مصادر الطاقة أكبر من اللازم. استخدم نقاط فصل واقعية (48 فولت، 30 فولت، إلخ).
هل يجب تعطيل التحميل الكسول لتحسين السرعة؟
لا. قم بتعطيله فقط لصورة LCP (غالبًا ما تكون أول صورة مرئية) وبعض مكونات جافا سكريبت (مثل أشرطة التمرير) عند الضرورة. يظل التحميل الكسول مفيدًا للصور. تحت خط الماء.
هل `fetchpriority="high"` كافٍ لتحسين LCP؟
هذا مفيد، ولكن إذا ظلت الصورة كبيرة جدًا (وهذا سيء). sizes(إذا لم يتوفر حجم وسيط مناسب أو كان التنسيق غير مُحسَّن)، فسيظل أداء LCP ضعيفًا. عالج المورد الصحيح (الحجم/التنسيق) أولًا، ثم أعطه الأولوية.
هل تستفيد صور الخلفية في CSS من خاصية srcset؟
لا. أنت بحاجة إلى استخدام استعلامات الوسائط CSS (خلفيات متعددة) أو، والأفضل من ذلك، استبدالها بخلفية حقيقية. <img> (أو <picture>) للسماح للمتصفح بالاختيار.
تقوم إضافة تحسين الصور الخاصة بي باستبدال عناوين URL: هل هذه مشكلة؟
قد يحدث ذلك إذا تسبب الملحق في تعطل srcset (عناوين URL غير صالحة، عرض غير متناسق، عناوين URL مكررة). اختبر ذلك عن طريق تعطيله مؤقتًا وقارن كود HTML المُنشأ.
أين ينبغي وضع هذه المقاطع بشكل صحيح؟
الخيار الأمثل هو استخدام إضافة صغيرة ذات إصدارات متعددة (أو إضافة متعددة). تجنب استخدام القالب الرئيسي. يُمكن استخدام قالب فرعي، ولكن قد يؤثر ذلك سلبًا على الأداء والمظهر.
ماذا لو قمت بتغيير أحجام الصور بعد ذلك؟
ستحتاج إلى إعادة إنشاء الصور المصغرة حتى تتمكن من srcset يقترح الأحجام الجديدة. قم بذلك في بيئة تجريبية، ثم جدولة العملية في بيئة الإنتاج (عملية دفعية، ساعات خارج أوقات الذروة)، خاصة إذا كان لديك مكتبة وسائط كبيرة.
كيف يمكنني تحديد أي صورة هي صورة LCP بدون استخدام أداة رسومية؟
بدون أداة للمتصفح، يصبح الأمر صعبًا. من ناحية البرمجة، يمكنك تطبيق قاعدة إرشادية (الصورة المميزة / أول صورة في المحتوى) والتحقق من تأثيرها على مقاييسك. وللتأكد، استخدم مقاييس الحقول (مراقبة تجربة المستخدم الحقيقية) أو تقارير الأداء من نظامك، لكن هذا خارج نطاق "البرمجة فقط" هنا.