إصلاح عدم ثبات التنسيق

جولة تفصيلية حول استخدام WebPageTest لتحديد مشاكل عدم ثبات التنسيق وإصلاحها.

في مشاركة سابقة، كتبت عن قياس متغيّرات التصميم التراكمية (CLS) في WebPageTest. إنّ متغيّرات التصميم التراكمية(CLS) هي عبارة عن تجميع لكل متغيّرات التصميم. لذا، في هذه المشاركة، أعتقد أنّه من المثير للاهتمام التعمق أكثر وفحص كل متغيّرات التصميم الفردية على الصفحة لمحاولة فهم الأسباب التي قد تؤدي إلى عدم الاستقرار ومحاولة حلّ المشاكل.

قياس متغيّرات التصميم

باستخدام واجهة برمجة التطبيقات Layout Instability API، يمكننا الحصول على قائمة بجميع أحداث متغيّرات التصميم على إحدى الصفحات:

new Promise(resolve => {
  new PerformanceObserver(list => {
    resolve(list.getEntries().filter(entry => !entry.hadRecentInput));
  }).observe({type: "layout-shift", buffered: true});
}).then(console.log);

وينتج عن ذلك مصفوفة من متغيّرات التصميم التي لا تسبقها أحداث إدخال:

[
  {
    "name": "",
    "entryType": "layout-shift",
    "startTime": 210.78500000294298,
    "duration": 0,
    "value": 0.0001045969445437389,
    "hadRecentInput": false,
    "lastInputTime": 0
  }
]

في هذا المثال، كان هناك تحوّل واحد صغير جدًا بنسبة 0.01% في 210 ملي ثانية.

تعد معرفة وقت وشدة التحول مفيدًا للمساعدة في تضييق نطاق الأسباب التي يمكن أن يكون قد تسبب في التحول. لنعد إلى WebPageTest من أجل استخدام بيئة معملية لإجراء مزيد من الاختبارات.

قياس متغيّرات التصميم في WebPageTest

على غرار قياس متغيّرات التصميم التراكمية (CLS) في WebPageTest، يتطلّب قياس متغيّرات التصميم الفردية مقياسًا مخصَّصًا. ولحسن الحظ، أصبحت العملية أسهل الآن بعد أن أصبح Chrome 77 ثابتًا. تكون واجهة برمجة التطبيقات Layout Instability API مفعَّلة تلقائيًا، لذا من المفترض أن تتمكّن من تنفيذ مقتطف JavaScript هذا على أي موقع إلكتروني ضمن Chrome 77 والحصول على النتائج على الفور. في WebPageTest، يمكنك استخدام متصفح Chrome التلقائي بدون القلق بشأن علامات سطر الأوامر أو استخدام إصدار Canary.

لنعدّل هذا النص البرمجي لإنشاء مقياس مخصّص لـ WebPageTest:

[LayoutShifts]
return new Promise(resolve => {
  new PerformanceObserver(list => {
    resolve(JSON.stringify(list.getEntries().filter(entry => !entry.hadRecentInput)));
  }).observe({type: "layout-shift", buffered: true});
});

يتحوّل الوعد في هذا النص البرمجي إلى تمثيل JSON للصفيف بدلاً من الصفيف نفسه. وذلك لأن المقاييس المخصّصة لا يمكنها أن تنتج سوى أنواع بيانات أولية، مثل السلاسل أو الأرقام.

الموقع الإلكتروني الذي سأستخدمه للاختبار هو ismyhostfastyet.com، وهو موقع أنشأته لمقارنة أداء التحميل الفعلي لمضيفي الويب في الواقع.

تحديد أسباب عدم استقرار التصميم

في النتائج، يمكننا أن نرى أن المقياس المخصّص LayoutShifts يحتوي على القيمة التالية:

[
  {
    "name": "",
    "entryType": "layout-shift",
    "startTime": 3087.2349999990547,
    "duration": 0,
    "value": 0.3422101449275362,
    "hadRecentInput": false,
    "lastInputTime": 0
  }
]

باختصار، هناك تغيّر واحد في التصميم بنسبة% 34.2 يحدث في 3087 ملي ثانية. للمساعدة في تحديد الجاني، لنستخدم عرض شريط الصور في WebPageTest.

خليتان في شريط الصور تعرض لقطات شاشة قبل متغيّرات التصميم وبعده.
خليتين في شريط الصور تعرض لقطات شاشة قبل متغيّرات التصميم وبعدها

إنّ الانتقال إلى علامة 3 ثوانٍ تقريبًا في شريط الصور يوضِّح لنا بالضبط سبب تغيُّر التصميم بنسبة% 34: الجدول الملوّن. يجلب الموقع الإلكتروني ملف JSON بشكل غير متزامن، ثم يعرضه في جدول. يكون الجدول فارغًا في البداية، لذا فإن انتظار ملئه عند تحميل النتائج هو السبب في التغيير.

عنوان خطوط ويب يظهر من العدم.
يظهر عنوان خط الويب من العدم.

لكن هذا ليس كل شيء. عند اكتمال عرض الصفحة في حوالي 4.3 ثانية، يمكننا ملاحظة أن <h1> للصفحة "هل مضيفي سريع بعد؟" تظهر من العدم. ويحدث ذلك لأنّ الموقع الإلكتروني يستخدم خطًا على الويب ولم يتّخذ أي خطوات لتحسين العرض. لا يبدو في الواقع أن التنسيق يتغير عندما يحدث ذلك، ولكن لا يزال يتعين على المستخدم الانتظار لفترة طويلة لقراءة العنوان.

إصلاح عدم ثبات التنسيق

والآن بعد أن عرفنا أن الجدول الذي يتم إنشاؤه بشكل غير متزامن يتسبب في تغيير ثلث إطار العرض، فقد حان الوقت لإصلاحه. لا نعرف محتوى الجدول إلى أن يتم تحميل نتائج JSON فعليًا، ولكن لا يزال بإمكاننا تعبئة الجدول بنوع من بيانات العنصر النائب حتى يكون التنسيق نفسه ثابتًا نسبيًا عند عرض نموذج العناصر في المستند (DOM).

إليك التعليمة البرمجية لإنشاء بيانات العنصر النائب:

function getRandomFiller(maxLength) {
  var filler = '█';
  var len = Math.ceil(Math.random() * maxLength);
  return new Array(len).fill(filler).join('');
}

function getRandomDistribution() {
  var fast = Math.random();
  var avg = (1 - fast) * Math.random();
  var slow = 1 - (fast + avg);
  return [fast, avg, slow];
}

// Temporary placeholder data.
window.data = [];
for (var i = 0; i < 36; i++) {
  var [fast, avg, slow] = getRandomDistribution();
  window.data.push({
    platform: getRandomFiller(10),
    client: getRandomFiller(5),
    n: getRandomFiller(1),
    fast,
    avg,
    slow
  });
}
updateResultsTable(sortResults(window.data, 'fast'));

يتم إنشاء بيانات العنصر النائب بشكل عشوائي قبل فرزها. يتضمن الحرف "█" الذي تكرر عددًا عشوائيًا من المرات لإنشاء عناصر نائبة مرئية للنص وتوزيع يتم إنشاؤه عشوائيًا للقيم الرئيسية الثلاث. أضفت أيضًا بعض الأنماط لإلغاء تشبع كل الألوان من الجدول لتوضيح أن البيانات لم يتم تحميلها بالكامل حتى الآن.

لا يهم مظهر العناصر النائبة التي تستخدمها في استقرار التنسيق. الغرض من العناصر النائبة هو طمأنة المستخدمين بظهور المحتوى وأنّ الصفحة غير معطّلة.

إليك كيفية ظهور العناصر النائبة أثناء تحميل بيانات JSON:

يتم عرض جدول البيانات مع بيانات العنصر النائب.
يتم عرض جدول البيانات مع بيانات العنصر النائب.

إنّ معالجة مشكلة الخط على الويب أبسط بكثير. بما أنّ الموقع الإلكتروني يستخدم Google Fonts، علينا تمرير السمة display=swap في طلب CSS. دِي كُلّْ حَاجَة تِخُصّْ. ستضيف Fonts API النمط font-display: swap في بيان الخط، ما يتيح للمتصفح عرض النص بخط احتياطي على الفور. في ما يلي الترميز المناسب مع تضمين الحلّ:

<link href="https://fonts.googleapis.com/css?family=Chivo:900&display=swap" rel="stylesheet">

التحقق من التحسينات

وبعد إعادة تشغيل الصفحة من خلال WebPageTest، يمكننا إنشاء مقارنة قبل وبعد لتصور الفرق وقياس الدرجة الجديدة من عدم استقرار التنسيق:

شريط صور WebPageTest يعرض تحميل الموقعين جنبًا إلى جنب مع تحسينات التنسيق أو بدونها.
شريط صور WebPageTest يعرض كلا الموقعين الإلكترونيين جنبًا إلى جنب مع تحسينات التنسيق أو بدونها.
[
  {
    "name": "",
    "entryType": "layout-shift",
    "startTime": 3070.9349999997357,
    "duration": 0,
    "value": 0.000050272187989256116,
    "hadRecentInput": false,
    "lastInputTime": 0
  }
]

وفقًا للمقياس المخصّص، ما زال هناك تغيير في التنسيق يحدث عند 3, 071 ملي ثانية (في الوقت نفسه تقريبًا، على الرغم من أنّ درجة خطورته أصغر كثيرًا: 0.005%. يمكنني التعايش مع هذا.

يتضح من شريط الصور أيضًا أنّ الخط <h1> يعود على الفور إلى خط النظام، ما يتيح للمستخدمين قراءته في وقت أقرب.

الخلاصة

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

(شيء آخر) قياس عدم ثبات التخطيط الذي يواجهه المستخدمون الحقيقيون

من الرائع أن تتمكّن من إجراء اختبار WebPageTest على صفحة قبل عملية التحسين وبعدها، وترى تحسُّنًا في أحد المقاييس، ولكن المهم حقًا هو تحسُّن تجربة المستخدم. أليس هذا هو السبب في أننا نحاول تحسين الموقع في المقام الأول؟

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

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