التدخل ضد document.write()

هل ظهر لك مؤخرًا تحذير مشابه لما يلي في وحدة تحكم المطوّرين في Chrome وتساءلت عن سبب إصداره؟

(index):34 A Parser-blocking, cross-origin script,
https://paul.kinlan.me/ad-inject.js, is invoked via document.write().
This may be blocked by the browser if the device has poor network connectivity.

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

أحد الأسباب المعروفة لضعف الأداء هو استخدام document.write() داخل الصفحات، وتحديدًا الاستخدامات التي تُدخل نصوصًا برمجية. كما تبدو هذه الخطوات بسيطة، إلا أنها يمكن أن تتسبب في مشكلات حقيقية للمستخدمين.

document.write('<script src="https://example.com/ad-inject.js"></script>');

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

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

لقد جمعنا البيانات من تجربة ميدانية لمدة 28 يومًا على 1٪ من مستخدمي Chrome الثابتين، وتقتصر على المستخدمين من خلال اتصالات الجيل الثاني. ولاحظنا أنّ% 7.6 من جميع عمليات تحميل الصفحات على شبكة الجيل الثاني تضمّنت نصًا برمجيًا واحدًا على الأقل لحظر المحللين اللغويين على مواقع إلكترونية متعددة وتم إدراجه من خلال document.write() في مستند المستوى الأعلى. نتيجةً لحظر تحميل هذه النصوص البرمجية، لاحظنا التحسينات التالية على عمليات التحميل:

  • 10% زيادة في عمليات تحميل الصفحات التي تؤدي إلى الوصول إلى سرعة عرض المحتوى على الصفحة (تأكيد مرئي للمستخدم بأنّ الصفحة يتم تحميلها بشكل فعّال)، و%25 زيادة في عمليات تحميل الصفحات لتصل إلى الحالة التي تم تحليلها بالكامل، و10% أقل من عمليات إعادة التحميل ما يشير إلى انخفاض في شعور المستخدمين بعدم الرضا
  • انخفاض بنسبة 21% في متوسط الوقت (أسرع من ثانية واحدة) حتى عرض سرعة عرض أول محتوى مرئي
  • انخفاض بنسبة 38% في متوسط الوقت الذي يستغرقه تحليل صفحة ما، وهو ما يمثل تحسّنًا بحوالي ست ثوانٍ، ما يقلل بشكل كبير من الوقت الذي يستغرقه عرض ما يهم المستخدم.

وبوضع هذه البيانات في الاعتبار، يتدخل Chrome نيابةً عن جميع المستخدمين، بدءًا من الإصدار 55، عند رصد هذا النمط السيئ المعروف من خلال تغيير طريقة التعامل مع document.write() في Chrome (الاطّلاع على حالة Chrome). على وجه التحديد، لن ينفِّذ Chrome عناصر <script> التي تم إدخالها عبر document.write() عند استيفاء جميع الشروط التالية:

  1. اتصال المستخدم بالإنترنت بطيء، لا سيما عند استخدام شبكة الجيل الثاني. (وفي المستقبل، قد يمتد التغيير ليشمل المستخدمين الآخرين الذين يستخدمون اتصالات بطيئة، مثل بطء شبكة الجيل الثالث أو بطء Wi-Fi).
  2. document.write() وارد في مستند المستوى الأعلى. ولا ينطبق هذا التدخل على النصوص البرمجية المكتوبة بشكل المستندات داخل إطارات iframe، وذلك لأنّها لا تحظر عرض الصفحة الرئيسية.
  3. يمنع النص البرمجي في document.write() المحلل اللغوي. سيستمر تنفيذ النصوص البرمجية التي تحتوي على السمة "async" أو "defer".
  4. عدم استضافة النص البرمجي على الموقع الإلكتروني نفسه. وبعبارة أخرى، لن يتدخّل Chrome في النصوص البرمجية ذات eTLD+1 المطابقة (مثل نص برمجي مستضاف على js.example.org يتم إدراجه في www.example.org).
  5. النص البرمجي غير موجود فعلاً في ذاكرة التخزين المؤقت لبروتوكول HTTP للمتصفح. لن تتسبب النصوص البرمجية في ذاكرة التخزين المؤقت في أي تأخير في الشبكة وستستمر في التنفيذ.
  6. لا تتم إعادة تحميل الطلب الخاص بالصفحة. ولن يتدخل Chrome إذا شغّل المستخدم إعادة التحميل وسينفذ الصفحة كالمعتاد.

تستخدم مقتطفات الجهات الخارجية أحيانًا document.write() لتحميل نصوص برمجية. لحسن الحظ، توفّر معظم الجهات الخارجية بدائل تحميل غير متزامن، والتي تسمح بتحميل النصوص البرمجية التابعة لجهات خارجية بدون حظر عرض باقي المحتوى على الصفحة.

كيف أحل هذه المشكلة؟

هذه الإجابة البسيطة لا تُدخل نصوصًا برمجية باستخدام document.write(). نحتفظ بمجموعة من الخدمات المعروفة لدعم برنامج التحميل غير المتزامن، والتي ننصحك بمواصلة التحقق منها.

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

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

إذا قدّم لك موفّر الخدمة مقتطفًا يتضمّن document.write()، يمكنك إضافة السمة async إلى عنصر النص البرمجي، أو إضافة عناصر النص البرمجي باستخدام واجهة برمجة تطبيقات DOM، مثل document.appendChild() أو parentNode.insertBefore().

كيفية اكتشاف تأثُّر موقعك الإلكتروني

هناك عدد كبير من المعايير التي تحدد ما إذا كان سيتم فرض القيود، فكيف تعرف ما إذا كنت ستتأثر؟

رصد ما إذا كان المستخدم يستخدم شبكة الجيل الثاني

لفهم التأثير المحتمل لهذا التغيير، يجب أولاً فهم عدد المستخدمين الذين يستخدمون شبكات الجيل الثاني. يمكنك اكتشاف نوع الشبكة الحالي للمستخدم وسرعته باستخدام واجهة برمجة تطبيقات معلومات الشبكة المتاحة في Chrome، ثم إرسال تنبيه إلى الأنظمة التحليلية أو أنظمة مقاييس المستخدم الحقيقية (RUM).

if(navigator.connection &&
    navigator.connection.type === 'cellular' &&
    navigator.connection.downlinkMax <= 0.115) {
    // Notify your service to indicate that you might be affected by this restriction.
}

رصد التحذيرات في "أدوات مطوري البرامج في Chrome"

منذ الإصدار 53 من Chrome، تُصدر "أدوات مطوري البرامج" تحذيرات بشأن عبارات document.write() التي تحتوي على مشاكل. وعلى وجه التحديد، إذا استوفى طلب document.write() المعايير من 2 إلى 5 (يتجاهل Chrome معايير الاتصال عند إرسال هذا التحذير)، سيظهر التحذير على النحو التالي:

تحذير بشأن كتابة المستند

إنّ ظهور تحذيرات في "أدوات مطوري البرامج في Chrome" أمر رائع، ولكن كيف يمكنك اكتشاف ذلك على نطاق واسع؟ يمكنك التحقق من عناوين HTTP التي يتم إرسالها إلى الخادم عند حدوث التدخل.

التحقّق من عناوين HTTP في مورد النص البرمجي

عند حظر نص برمجي مدرَج عبر document.write، سيرسل Chrome العنوان التالي إلى المورد المطلوب:

Intervention: <https://shorturl/relevant/spec>;

عند العثور على نص برمجي مدرَج عبر document.write وقد يتم حظره في ظروف مختلفة، قد يرسل Chrome ما يلي:

Intervention: <https://shorturl/relevant/spec>; level="warning"

سيتم إرسال عنوان التدخل كجزء من طلب GET للنص البرمجي (بشكل غير متزامن في حالة تدخل فعلي).

ما الذي يحمله المستقبل في جعبته؟

الخطة الأولية هي تنفيذ هذا التدخل عندما نكتشف المعايير التي يتم استيفاؤها. بدأنا بعرض تحذير فقط في Play Console في الإصدار 53 من Chrome. (تم استخدام الإصدار التجريبي في تموز (يوليو) 2016. ونتوقع أن يتوفر الإصدار الثابت لجميع المستخدمين في أيلول (سبتمبر) 2016).

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

نحن نسعى بمرور الوقت إلى التدخل لمعالجة أي مشاكل لدى أي مستخدم (أي بطء الاتصال بشبكة الجيل الثالث أو WiFi). اتّبِع إدخال حالة Chrome هذا.

هل يهمّك معرفة المزيد من المعلومات؟

لمزيد من المعلومات، يُرجى الاطّلاع على هذه المراجع الإضافية: