تحسين إغلاق الصفحة في تنسيق XMLHttpRequest() متزامنًا

تقليل عمليات التنقّل المتأخرة

جو ميدلي
جو ميدلي

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

ويجب تغيير هذه الممارسة، والمتصفّحات تستجيب. إنّ مواصفات "XMLHttpRequest()" محددة بالفعل للإيقاف النهائي والإزالة. يتخذ Chrome 80 الخطوة الأولى من خلال منع المكالمات المتزامنة داخل العديد من معالِجات الأحداث، والأخص beforeunload وunload وpagehide وvisibilitychange عند تنشيطها عند إغلاق التطبيق. كما حصلت WebKit مؤخرًا على التزام بتنفيذ تغيير السلوك نفسه.

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

عمليات الإيقاف المؤقتة

لا يريد Chrome ببساطة سحب القابس على XMLHttpRequest()، وهذا هو سبب توفّر بعض خيارات الإيقاف المؤقتة. بالنسبة إلى المواقع الإلكترونية على الإنترنت، تتوفّر نسخة تجريبية أصلية. تتيح لك هذه الخطوة إضافة رمز مميّز خاص بالمصدر إلى عناوين الصفحات التي تتيح طلبات XMLHttpRequest() المتزامنة. ينتهي هذا الخيار قبل فترة وجيزة من شحن Chrome 89، في وقت ما في آذار (مارس) 2021. ويمكن لعملاء Chrome Enterprise أيضًا استخدام علامة السياسة AllowSyncXHRInPageDismissal التي تنتهي في الوقت نفسه.

البدائل

بغض النظر عن كيفية إعادة إرسال البيانات إلى الخادم، من الأفضل تجنُّب الانتظار حتى يتم إلغاء تحميل الصفحة من أجل إرسال جميع البيانات دفعة واحدة. بالإضافة إلى ترك انطباع سيئ لدى المستخدم، فإن عملية إلغاء التحميل غير موثوقة في المتصفحات الحديثة كما أنها تخاطر بفقدان البيانات في حال حدوث خطأ ما. وعلى وجه التحديد، غالبًا لا يتم تنشيط أحداث إلغاء التحميل على متصفّحات الأجهزة الجوّالة لأن هناك طرق عديدة لإغلاق علامة تبويب أو متصفّح على أنظمة تشغيل الأجهزة الجوّالة بدون تنشيط حدث unload. مع XMLHttpRequest()، كان اختيار الحمولات الصغيرة هو الاختيار. الآن هو أحد المتطلبات. ويبلغ الحدّ الأقصى لتحميل المحتوى البديل 64 كيلوبايت لكلّ سياق، حسب ما تقتضي المواصفات.

استرجاع رسالة التحقّق من الاتصال

توفر جلب واجهة برمجة التطبيقات وسيلة قوية للتعامل مع تفاعلات الخادم وواجهة متناسقة للاستخدام عبر واجهات برمجة التطبيقات المختلفة للأنظمة الأساسية. ومن بين خياراتها keepalive، والتي تضمن استمرار الطلب، سواء بقيت الصفحة التي جعلتها مفتوحة أم لا:

window.addEventListener('unload', {
  fetch('/siteAnalytics', {
    method: 'POST',
    body: getStatistics(),
    keepalive: true
  });
}

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

SendBeacon()

يستخدم SendBeacon() واجهة برمجة تطبيقات الجلب لاحقًا، وهذا هو السبب في لديه حد الحمولة نفسه البالغ 64 كيلوبايت ولماذا يضمن أيضًا استمرار الطلب بعد إلغاء تحميل الصفحة. ميزتها الأساسية هي بساطتها. يتيح لك إرسال بياناتك بسطر واحد من التعليمات البرمجية:

window.addEventListener('unload', {
  navigator.sendBeacon('/siteAnalytics', getStatistics());
}

الخلاصة

مع تزايد مدى توفّر fetch() في جميع المتصفحات، نأمل أن تتم إزالة XMLHttpRequest() من منصة الويب في وقت ما. يوافق موردو المتصفح على أنه يجب إزالته، لكن الأمر سيستغرق بعض الوقت. يُعد التوقف عن إحدى أسوأ حالات الاستخدام الخاصة بها خطوة أولى تعمل على تحسين تجربة المستخدم للجميع.

صورة من تصوير ماثيو هاملتون على UnLaunch