وحدات التحميل المُسبق

Sérgio Gomes

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

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

<link rel="preload"> هو وسيلة لطلب الموارد بشكل صريح مسبقًا، قبل أن يحتاجها المتصفح.

<head>
  <link rel="preload" as="style" href="critical-styles.css">
  <link rel="preload" as="font" crossorigin type="font/woff2" href="myfont.woff2">
</head>

دعم المتصفح

  • Chrome: 50.
  • الحافة: 79 أو أقل
  • Firefox: 85.
  • Safari: الإصدار 11.1.

المصدر

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

يوفّر <link rel="preload"> وما يعادلها لعنوان HTTP رابطًا بسيطًا وتعريفيًا لإعلام المتصفّح مباشرةً بالملفات المهمّة التي ستكون مطلوبة كجزء من التنقل الحالي. عندما يلاحظ المتصفّح التحميل المُسبق، يبدأ معدّل مرتفع. ذات الأولوية للتنزيل للمورد، بحيث يكون الوقت المناسب قد تم جلبها بالفعل أو هناك جزئيًا. ومع ذلك، فإنه لا يصلح مع الوحدات.

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

بالنسبة إلى علامتَي <script> و<link>، يمكنك ضبط وضع بيانات الاعتماد باستخدام crossorigin. . ومع ذلك، يتضح أن <script type="module"> بدون تشير السمة crossorigin إلى وضع بيانات اعتماد omit، وهو غير متوفّر. مقابل <link rel="preload">. هذا يعني أنه سيتعين عليك غيِّر السمة crossorigin في كل من <script> و<link> إلى قيمة واحدة. القيم الأخرى، وقد لا تكون لديك طريقة سهلة للقيام بذلك إذا محاولة التحميل المسبق هو تبعية الوحدات الأخرى.

فضلاً عن ذلك، إنّ جلب الملف هو الخطوة الأولى فقط في تشغيل الرمز. أولاً، يجب على المتصفح تحليلها وتجميعها. من الناحية المثالية، ويجب أن يحدث ذلك في وقت مبكر أيضًا، بحيث عندما تكون هناك حاجة إلى الوحدة، يتم وضع جاهزة للتشغيل. في المقابل، يُحلّل V8 (محرك JavaScript في Chrome) الوحدات ويجمعها. بشكل مختلف عن لغة JavaScript الأخرى إجراء <link rel="preload"> لا توفر أي طريقة للإشارة إلى أن الملف الذي يتم تحميله هو وحدة، وبالتالي فإن كل القيام به هو تحميل الملف ووضعه في ذاكرة التخزين المؤقت. بعد تحميل النص البرمجي باستخدام <script type="module"> (أو تم تحميلها بواسطة وحدة أخرى)، يحلّل المتصفّح وتجمع الرمز كوحدة JavaScript.

باختصار، نعم. من خلال توفُّر نوع link محدّد لوحدات التحميل المُسبق، يمكننا كتابة HTML بسيط دون القلق بشأن وضع بيانات الاعتماد الذي نستخدمه. تشير رسالة الأشكال البيانية فإن الإعدادات الافتراضية تعمل فقط.

<head>
  <link rel="modulepreload" href="super-critical-stuff.mjs">
</head>
[...]
<script type="module" src="super-critical-stuff.mjs">

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

دعم المتصفح

  • الإصدار 66 من متصفّح Chrome
  • الحافة: 79 أو أقل
  • Firefox: 115.
  • Safari: 17.

المصدر

ولكن ماذا عن الوحدات والتبعيات؟

مضحك! عليكم طرح هذا السؤال. هناك شيء ما لم تتناوله هذه المقالة: التكرار.

في الواقع، تسمح مواصفات <link rel="modulepreload"> بالتحميل اختياريًا، وليس فقط الوحدة المطلوبة، ولكن أيضًا كل شجرة تبعيتها. لا ينبغي أن تقوم المتصفحات للقيام بذلك، لكنهم يستطيعون ذلك.

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

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

<head>
  <!-- dog.js imports dog-head.js, which in turn imports
       dog-head-mouth.js, which imports dog-head-mouth-tongue.js. -->
  <link rel="modulepreload" href="dog-head-mouth-tongue.mjs">
  <link rel="modulepreload" href="dog-head-mouth.mjs">
  <link rel="modulepreload" href="dog-head.mjs">
  <link rel="modulepreload" href="dog.mjs">
</head>

هل تساعد وحدات التحميل المُسبق في تحسين الأداء؟

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

مع ذلك، لا يزال أداء الوحدة جاريًا، لذا يجب التأكد من تُلقي نظرة عن كثب على ما يحدث في تطبيقك باستخدام أدوات المطوّرين، ففكر في تجميع تطبيقك في عدة أجزاء في غضون ذلك. هناك الكثير من باستمرار في Chrome، لذلك نحن نقترب من تقديم يجمعون بين الراحة التي حصلوا عليها!