كسول تحميل الصور باستخدام IntersectionObserver

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

الصورة

أحكام عامة


خذ بعين الاعتبار ، على سبيل المثال ، الصفحة الرئيسية لقسم المنزل في Walmart.


صفحة تحتوي على العديد من الصور

إليك معلومات حول عدد الصور التي يتم تحميلها لتكوين هذه الصفحة:


تحميل الصور أثناء تكوين الصفحة

كما ترون ، هناك 137 صورة! وهذا يعني أن أكثر من 80٪ من البيانات المطلوبة لعرض الصفحة والمرسلة عبر الشبكة يتم تقديمها كملفات رسومية.

الآن نقوم بتحليل طلبات الشبكة التي يتم تنفيذها عند تحميل الصفحة:


تنفيذ طلبات الشبكة أثناء تكوين الصفحة

في هذه الحالة ، يتم تنزيل الملفات الناتجة عن فصل رمز المشروع في وقت لاحق عما يمكن. هذا يرجع إلى حقيقة أنك تحتاج أولاً إلى تحميل الحزمة الرئيسية cp_ny.bundle . يمكن تنزيل هذه الحزمة بشكل أسرع بكثير إذا لم يزعجها 18 صورة تتنافس مع بعضها البعض لعرض النطاق الترددي.

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

مشروع تجريبي


لنبدأ بمكون تفاعل Image البسيط للغاية:

 class Image extends PureComponent { render() {   const { src } = this.props;   return <img align="center" src={src} />; } } 

يأخذ ، باعتباره خاصية ، URL ، ويستخدم لتقديم عنصر img HTML. إليك رمز JSFiddle ذي الصلة. توضح الصورة التالية الصفحة التي تحتوي على هذا المكون. يرجى ملاحظة أنه من أجل رؤية الصورة المعروضة من قبله ، تحتاج إلى التمرير محتويات الصفحة.


الصفحة التي تحتوي على المكون الذي يعرض الصورة

من أجل تنفيذ تقنية التحميل البطيء للصور في هذا المكون ، تحتاج إلى تنفيذ الخطوات الثلاث التالية:

  1. لا تعرض الصورة مباشرة بعد التنزيل.
  2. قم بإعداد أدوات للكشف عن مظهر صورة في منطقة العرض لمحتوى الصفحة.
  3. اعرض الصورة بعد اكتشاف أنها سقطت في منطقة العرض.

دعونا نلقي نظرة على هذه الخطوات.

الخطوة الأولى


في هذه الخطوة ، لا يتم عرض الصورة مباشرة بعد التحميل.

 render() { return <img />; } 

الخطوة الثانية


نقوم هنا بتكوين الآليات التي تسمح لنا باكتشاف اللحظة التي تدخل فيها الصورة إلى منطقة العرض.

 componentDidMount() { this.observer = new IntersectionObserver(() => {   //        }, {   root: document.querySelector(".container") }); this.observer.observe(this.element); } .... render() { return <img ref={el => this.element = el} />; } 

دعونا نحلل هذا الرمز. إليك ما تم القيام به هنا:

  • تمت إضافة سمة المرجع إلى عنصر img . يسمح لك هذا بتحديث رابط الصورة لاحقًا في src دون الحاجة إلى إعادة عرض المكون.
  • تم إنشاء نسخة جديدة من IntersectionObserver (سنتحدث عن هذا أدناه).
  • تتم مطالبة كائن IntersectionObserver بمراقبة الصورة باستخدام observe(this.element) .

ما هو IntersectionObserver ؟ بالنظر إلى أن كلمة "تقاطع" تُترجم على أنها "تقاطع" و "مراقب" هي "مراقب" ، يمكن للمرء بالفعل أن يخمن دور هذا الكائن. إذا كنت تبحث عن معلومات حول ذلك على MDN ، يمكنك معرفة أن واجهة Intersection Observer API تسمح لتطبيقات الويب بمراقبة التغييرات غير المتزامنة في تقاطع عنصر مع أصله أو نطاق مستند إطار العرض.

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

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

الخطوة الثالثة


نحتاج الآن إلى تكوين رد الاتصال الذي يتم استدعاؤه عندما يكتشف تقاطع العنصر target ( this.element في حالتنا) مع الحاوية root (في حالتنا ، فهو عنصر div .container ).

 .... this.observer = new IntersectionObserver( entries => {   entries.forEach(entry => {     const { isIntersecting } = entry;     if (isIntersecting) {       this.element.src = this.props.src;       this.observer = this.observer.disconnect();     }   }); }, {   root: document.querySelector(".container") } ); .... 

عندما يتم الكشف عن التقاطع ، entries نقل صفيف entries إلى entries ، والذي يشبه مجموعة من لقطات لحالة جميع العناصر المستهدفة التي تم الكشف عن تقاطع الحد المحدد لها. تشير الخاصية isIntersecting إلى اتجاه التقاطع. إذا كان العنصر الذي تتم مراقبته يقع خارج عنصر الجذر ، فهذا true . إذا غادر عنصر العنصر الجذر ، فهو false .

لذلك ، عندما اتضح أن العنصر قد تقاطع مع الحد السفلي للحاوية ، قمت يدويًا بتعيين خاصية src وإيقاف تشغيل المراقبة ، والتي لم تعد ضرورية.

الخطوة 4 (سرية)


الآن ، في الخطوة الرابعة السرية لعملنا ، يمكنك الاستمتاع بالنتيجة والاستمتاع بالنجاح. هذا هو الرمز الذي يجمع ما تحدثنا عنه للتو.


نتيجة تطبيق تقنية تحميل الصور البطيئة

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


سلوك الصفحة عند التمرير بسرعة وإبطاء سرعة اتصال الشبكة

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

صحيح أن التعامل مع هذه المشكلة ليس بالأمر الصعب. يمكن القيام بذلك بسبب حقيقة أن واجهة Intersection Observer API توفر للمطور القدرة على توسيع أو تضييق حدود العنصر الجذر (في حالتنا ، هذا هو عنصر .container .). لاستخدام هذه الفرصة ، ما عليك سوى إضافة سطر واحد من التعليمات البرمجية إلى حيث تم تكوين الحاوية الجذر:

 rootMargin: "0px 0px 200px 0px" 

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

هذا هو الرمز الذي يطبق هذه التقنية.


تحسين تقنية تحميل الصور البطيئة

ونتيجة لذلك ، اتضح أنه عندما نقوم بتمرير الصفحة إلى العنصر الرابع من القائمة فقط ، يتم تحميل الصورة في منطقة تقع على بعد 200 بكسل أسفل المنطقة المرئية من الصفحة.
الآن ، يبدو أن كل ما هو مطلوب فعله. لكن الأمر ليس كذلك.

مشكلة ارتفاع الصورة


إذا كنت قد درست بعناية رسومات GIF أعلاه ، فقد تلاحظ أن شريط التمرير "يقفز" بعد تحميل الصورة. لحسن الحظ ، من السهل التعامل مع هذه المشكلة. السبب هو أن العنصر الذي يعرض الصورة في البداية يبلغ ارتفاعه 0 ، والذي بعد تحميل الصورة ، يتحول إلى 300 بكسل. لذلك ، لإصلاح المشكلة ، يكفي تعيين العنصر على ارتفاع ثابت عن طريق إضافة height={300} السمة height={300} إلى الصورة.

حول نتائج التحسين


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


تم إنشاء تقرير المنارة قبل التحسين


تم إنشاء تقرير المنارة بعد التحسين

الملخص


اليوم نظرنا إلى تقنية لتحسين صفحات الويب باستخدام تحميل الصور البطيئة. إذا كانت صفحات موقعك مليئة بالصور ، فربما تكون هذه التقنية مفيدة لك.

أعزائي القراء! كيف تقوم بتحسين الصور وتحميلها؟

Source: https://habr.com/ru/post/ar423485/


All Articles