هناك طريقتان للجلب المسبق: العلامات <link> وعناوين HTTP

ديميان رينزولي
ديميان رينزولي

في هذا الدرس التطبيقي حول الترميز، سيتم تنفيذ الجلب المُسبَق بطريقتَين: باستخدام <link rel="prefetch"> وعنوان HTTP Link.

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

قياس الأداء

حدِّد أولاً الأداء الأساسي:

  1. انقر على إنشاء ريمكس لتعديله ليصبح المشروع قابلاً للتعديل.
  2. لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق، ثم اضغط على ملء الشاشة ملء الشاشة.
  3. اضغط على "Control+Shift+J" (أو "Command+Option+J" على نظام التشغيل Mac) لفتح "أدوات مطوّري البرامج".
  4. انقر على علامة التبويب الشبكة.

  5. في القائمة المنسدلة التقييد، اختر شبكة الجيل الثالث السريعة لمحاكاة نوع اتصال بطيء.

  6. لتحميل صفحة المنتج، انقر على الشراء الآن في نموذج التطبيق.

يستغرق تحميل صفحة product-details.html 600 ملي ثانية تقريبًا:

لوحة شبكة تعرض أوقات تحميل product-details.html

لتحسين التنقّل، أدرِج علامة prefetch في الصفحة المقصودة لجلب صفحة product-details.html مُسبقًا:

  • أضِف عنصر <link> التالي إلى رأس ملف views/index.html:
<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">

      <link rel="prefetch" href="/product-details.html" as="document">
      ...
</head>

إنّ السمة as اختيارية ولكن ننصح بها، فهي تساعد المتصفّح في ضبط العناوين الصحيحة وتحديد ما إذا كان المورد متوفّرًا حاليًا في ذاكرة التخزين المؤقت. تشمل أمثلة قيم هذه السمة: document وscript وstyle وfont وimage وغير ذلك.

للتأكّد من عمل الجلب المُسبَق:

  1. لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق، ثم اضغط على ملء الشاشة ملء الشاشة.
  2. اضغط على "Control+Shift+J" (أو "Command+Option+J" على نظام التشغيل Mac) لفتح "أدوات مطوّري البرامج".
  3. انقر على علامة التبويب الشبكة.

  4. في القائمة المنسدلة التقييد، اختر شبكة الجيل الثالث السريعة لمحاكاة نوع اتصال بطيء.

  5. أزِل العلامة من مربّع الاختيار Disable cache (تعطيل ذاكرة التخزين المؤقت).

  6. أعِد تحميل التطبيق.

الآن، عند تحميل الصفحة المقصودة، يتم تحميل صفحة product-details.html أيضًا، ولكن بأقل أولوية:

لوحة شبكة تعرض product-details.html تم جلبه مسبقًا.

يتم الاحتفاظ بالصفحة في ذاكرة التخزين المؤقت لبروتوكول HTTP لمدة خمس دقائق، وبعد ذلك يتم تطبيق قواعد Cache-Control العادية للمستند. في هذه الحالة، يتضمّن product-details.html عنوان cache-control بقيمة public, max-age=0، ما يعني أنّه يتم الاحتفاظ بالصفحة لمدة خمس دقائق في المجمل.

إعادة تقييم الأداء

  1. أعِد تحميل التطبيق.
  2. لتحميل صفحة المنتج، انقر على الشراء الآن في نموذج التطبيق.

ألقِ نظرة على لوحة الشبكة. هناك اختلافان مقارنةً بتتبُّع الشبكة الأولي:

  • يعرض عمود الحجم "ذاكرة التخزين المؤقت للجلب المُسبَق"، ما يعني أنّه تم استرداد هذا المورد من ذاكرة التخزين المؤقت في المتصفّح بدلاً من الشبكة.
  • يُظهر عمود الوقت أنّ الوقت الذي يستغرقه تحميل المستند يبلغ الآن 10 ملي ثانية تقريبًا.

وهذا انخفاض بنسبة 98% تقريبًا مقارنةً بالنسخة السابقة، والتي استغرقت حوالي 600 ملي ثانية.

لوحة شبكة تعرض تفاصيل product-details.html التي تم استردادها من ذاكرة التخزين المؤقت للجلب المُسبَق

رصيد إضافي: استخدام prefetch كتحسين تدريجي

ويتم تنفيذ الجلب المسبق على أفضل نحو كتحسين تدريجي للمستخدمين الذين يتصفحون عبر اتصالات سريعة. يمكنك استخدام Network Information API للتحقّق من أحوال الشبكة واستنادًا إلى ذلك عن طريق إدخال علامات الجلب المُسبَق ديناميكيًا. بهذه الطريقة، يمكنك تقليل استهلاك البيانات وتوفير التكاليف للمستخدمين في خطط البيانات البطيئة أو المكلفة.

لتنفيذ الجلب المُسبَق التكيّفي، عليك أولاً إزالة علامة <link rel="prefetch"> من views/index.html:

<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
       <link rel="prefetch" href="/product-details.html" as="document">
       ...
    </head>

بعد ذلك، أضِف الرمز التالي إلى public/script.js للإعلان عن دالة تُدخل علامة prefetch ديناميكيًا عندما يكون المستخدم متصلاً بالإنترنت:

function injectLinkPrefetchIn4g(url) {
    if (window.navigator.connection.effectiveType === '4g') {
        //generate link prefetch tag
        const linkTag = document.createElement('link');
        linkTag.rel = 'prefetch';
        linkTag.href = url;
        linkTag.as = 'document';

        //inject tag in the head of the document
        document.head.appendChild(linkTag);
    }
}

تعمل هذه الدالة على النحو التالي:

  • تتحقّق من السمة effectiveType في Network Information API لتحديد ما إذا كان المستخدم يستخدم اتصالًا بشبكة الجيل الرابع (أو أسرع).
  • في حال استيفاء هذا الشرط، يتم إنشاء علامة <link> مع prefetch كنوع التلميح، وتمرير عنوان URL الذي سيتم جلبه مُسبقًا في السمة href، ويشير إلى أنّ المورد هو document HTML في السمة as.
  • وأخيرًا، يتم إدخال النص البرمجي بشكل ديناميكي في head من الصفحة.

بعد ذلك، أضِف script.js إلى views/index.html، قبل علامة الإغلاق </body> مباشرةً:

<body>
      ...
      <script src="/script.js"></script>
</body>

إنّ طلب الرمز script.js في نهاية الصفحة يضمن أنّه سيتم تحميله وتنفيذه بعد تحليل الصفحة وتحميلها.

للتأكّد من عدم تداخل الجلب المُسبَق مع الموارد المهمة للصفحة الحالية، أضِف مقتطف الرمز التالي لطلب injectLinkPrefetchIn4g() في حدث window.load:

<body>
      ...
      <script src="/script.js"></script>
      <script>
           window.addEventListener('load', () => {
                injectLinkPrefetchIn4g('/product-details.html');
           });
      </script>
</body>

لا تجلب الصفحة المقصودة الآن product-details.html مُسبقًا إلا من خلال الاتصالات السريعة. للتأكّد من ذلك:

  1. لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق، ثم اضغط على ملء الشاشة ملء الشاشة.
  2. اضغط على "Control+Shift+J" (أو "Command+Option+J" على نظام التشغيل Mac) لفتح "أدوات مطوّري البرامج".
  3. انقر على علامة التبويب الشبكة.
  4. في القائمة المنسدلة تقييد، اختَر على الإنترنت.
  5. أعِد تحميل التطبيق.

من المفترض أن يظهر لك product-details.html في لوحة "الشبكة":

لوحة شبكة تعرض product-details.html تم جلبه مسبقًا.

للتأكّد من أنّ صفحة المنتج لم يتم جلبها مسبقًا عند استخدام الاتصالات البطيئة، اتّبِع الخطوات التالية:

  1. في القائمة المنسدلة "التقييد"، اختَر بطء شبكة الجيل الثالث.
  2. أعِد تحميل التطبيق.

يجب أن لا تتضمّن لوحة الشبكة سوى موارد الصفحة المقصودة التي لا تحتوي على السمة product-details.html:

لوحة الشبكة تعرض product-details.html لم يتم جلبه مسبقًا.

يمكن استخدام عنوان HTTP Link لجلب نوع الموارد نفسه مسبقًا للعلامة link. يعتمد تحديد وقت استخدام أحدهما أو الآخر في الغالب على اختيارك، لأنّ الفرق في الأداء ليس كبيرًا. في هذه الحالة، ستستخدمه لجلب صفحة CSS الرئيسية مسبقًا لصفحة المنتج، وذلك لتحسين عرضها.

أضِف عنوان HTTP Link الخاص بـ style-product.css في استجابة الخادم للصفحة المقصودة:

  1. افتح الملف server.js وابحث عن معالج get() لعنوان URL الجذر: /.
  2. أضِف السطر التالي في بداية المعالج:
app.get('/', function(request, response) {
    response.set('Link', '</style-product.css>; rel=prefetch');
    response.sendFile(__dirname + '/views/index.html');
});
  1. لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق، ثم اضغط على ملء الشاشة ملء الشاشة.
  2. اضغط على "Control+Shift+J" (أو "Command+Option+J" على نظام التشغيل Mac) لفتح "أدوات مطوّري البرامج".
  3. انقر على علامة التبويب الشبكة.
  4. أعِد تحميل التطبيق.

يتم الآن جلب style-product.css مسبقًا بأولوية أدنى بعد تحميل الصفحة المقصودة:

لوحة شبكة تعرض style-product.css تم جلبه مسبقًا.

للانتقال إلى صفحة المنتج، انقر على الشراء الآن. ألقِ نظرة على لوحة الشبكة:

لوحة شبكة تعرض تنسيق style-product.css الذي تم استرداده من ذاكرة التخزين المؤقت للجلب المُسبَق.

يتم استرداد ملف style-product.css من "ذاكرة التخزين المؤقت للجلب المُسبَق" واستغرق تحميله 12 ملي ثانية فقط.