حالة استخدام عامل ويب ملموس

في الوحدة الأخيرة، تم تقديم نظرة عامة على العاملين على الويب. يمكن للعاملين على الويب لتحسين استجابة الإدخال من خلال نقل JavaScript خارج سلسلة المحادثات الرئيسية إلى سلاسل محادثات منفصلة للعاملين على الويب، والتي يمكن أن تساعد في تحسين تفاعل موقعك الإلكتروني مدى استجابة الصفحة لتفاعلات المستخدم (INP) عندما يكون لديك عمل لا يحتاج إلى الوصول المباشر إلى السلسلة الرئيسية. ومع ذلك، فإن النظرة العامة وحدها ليست كافية، وفي هذه الوحدة، يتم عرض حالة استخدام ملموسة لعامل الويب.

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

ومع ذلك، فإنّ منطق استرجاع صورة وتحويلها إلى ArrayBuffer وقد يكون استخراج بيانات Exif الوصفية مكلفًا إذا تمّ إجراؤها بالكامل في سلسلة التعليمات الرئيسية لحسن الحظ، يسمح نطاق عامل الويب بإنجاز هذا العمل خارج سلسلة التعليمات الرئيسية. وبعد ذلك، وباستخدام مسار المراسلة لدى عامل تشغيل الويب، يتم نقل بيانات EXIF الوصفية إلى سلسلة التعليمات الرئيسية كسلسلة HTML يتم عرضه للمستخدم.

كيف تبدو سلسلة التعليمات الرئيسية بدون عامل ويب

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

  1. افتح علامة تبويب جديدة في Chrome ثم افتح "أدوات مطوري البرامج" الخاصة بها.
  2. افتح لوحة الأداء.
  3. انتقِل إلى https://exif-worker.glitch.me/without-worker.html.
  4. في لوحة الأداء، انقر على تسجيل في أعلى يسار صفحة جزء "أدوات مطوري البرامج"
  5. الصق رابط الصورة هذا، أو رابط آخر من اختيارك ويحتوي على بيانات Exif. البيانات الوصفية: في الحقل والنقر على الزر الحصول على ملف JPEG!.
  6. بعد تعبئة الواجهة ببيانات Exif الوصفية، انقر على Record (تسجيل) مرة أخرى إيقاف التسجيل.
محلّل أداء يعرض نشاط تطبيق أداة استخراج البيانات الوصفية للصور الذي يحدث بالكامل في سلسلة المحادثات الرئيسية هناك مهمتان طويلتان أساسيتان، إحداهما تُجريان عملية جلب للحصول على الصورة المطلوبة وفك ترميزها، وأخرى تستخرج البيانات الوصفية من الصورة.
نشاط سلسلة المحادثات الرئيسية في تطبيق استخراج البيانات الوصفية للصور لاحظ أن جميع حدوث النشاط في سلسلة التعليمات الرئيسية

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

  1. يأخذ النموذج الإدخال ويرسل طلب fetch للحصول على الإدخال الأولي جزء من الصورة يحتوي على بيانات Exif.
  2. يتم تحويل بيانات الصورة إلى ملف ArrayBuffer.
  3. يُستخدم نص exif-reader لاستخراج بيانات Exif الوصفية من .
  4. يتم سرقة بيانات التعريف لإنشاء سلسلة HTML، والتي تقوم بعد ذلك بتعبئة عارض البيانات الوصفية.

والآن قارِن ذلك مع تطبيق السلوك نفسه، ولكن استخدام واجهة عامل!

شكل سلسلة المحادثات الرئيسية مع عامل على الويب

والآن بعد أن رأيت كيف يمكن استخراج بيانات Exif الوصفية من JPEG في سلسلة التعليمات الرئيسية، فألقِ نظرة على الشكل الذي يظهر عليه محتوى الويب جميع الموظفين:

  1. افتح علامة تبويب أخرى في Chrome ثم افتح "أدوات مطوري البرامج" الخاصة بها.
  2. افتح لوحة الأداء.
  3. انتقِل إلى https://exif-worker.glitch.me/with-worker.html.
  4. في لوحة الأداء، انقر على زر التسجيل في أعلى يسار الصفحة. اليمنى من جزء "أدوات مطوري البرامج".
  5. الصِق رابط الصورة هذا في الحقل وانقر على الزر الحصول على ملف JPEG!.
  6. بعد تعبئة الواجهة ببيانات Exif الوصفية، انقر على زر التسجيل. مجددًا لإيقاف التسجيل.
محلّل أداء يعرض نشاط تطبيق أداة استخراج البيانات الوصفية للصور الذي يحدث في سلسلة المحادثات الرئيسية وسلسلة مشغّلات الويب وعلى الرغم من أنّ سلسلة المهام الرئيسية لا تزال طويلة، إلا أنّها تكون أقصر إلى حدّ كبير، إذ يتم جلب الصور وفك ترميزها واستخراج البيانات الوصفية بالكامل من خلال سلسلة تعليمات عامل الويب. يتضمن عمل سلسلة التعليمات الرئيسية الوحيد تمرير البيانات من وإلى عامل الويب.
نشاط سلسلة المحادثات الرئيسية في تطبيق استخراج البيانات الوصفية للصور لاحظ أن هناك مؤشر ترابط عاملي ويب إضافي يتم من خلاله إنجاز معظم العمل.

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

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

الآن لنتعمق في التعليمات البرمجية الخاصة بالعاملين على الويب والتي تجعل كل هذا ممكنًا!

نظرة على رمز عاملي الويب

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

ابدأ برمز سلسلة التعليمات الرئيسي الذي يجب أن يحدث قبل أن يتمكّن عامل الويب أدخل الصورة:

// scripts.js

// Register the Exif reader web worker:
const exifWorker = new Worker('/js/with-worker/exif-worker.js');

// We have to send image requests through this proxy due to CORS limitations:
const imageFetchPrefix = 'https://res.cloudinary.com/demo/image/fetch/';

// Necessary elements we need to select:
const imageFetchPanel = document.getElementById('image-fetch');
const imageExifDataPanel = document.getElementById('image-exif-data');
const exifDataPanel = document.getElementById('exif-data');
const imageInput = document.getElementById('image-url');

// What to do when the form is submitted.
document.getElementById('image-form').addEventListener('submit', event => {
  // Don't let the form submit by default:
  event.preventDefault();

  // Send the image URL to the web worker on submit:
  exifWorker.postMessage(`${imageFetchPrefix}${imageInput.value}`);
});

// This listens for the Exif metadata to come back from the web worker:
exifWorker.addEventListener('message', ({ data }) => {
  // This populates the Exif metadata viewer:
  exifDataPanel.innerHTML = data.message;
  imageFetchPanel.style.display = 'none';
  imageExifDataPanel.style.display = 'block';
});

يتم تشغيل هذا الرمز في سلسلة التعليمات الرئيسية، ويُعِدّ النموذج لإرسال عنوان URL للصورة إليه عامل الويب. من هناك، يبدأ رمز العامل على الويب بـ importScripts تُحمِّل النص البرمجي الخارجي exif-reader، ثم تُعِدّ مسار الرسائل إلى سلسلة المحادثات الرئيسية:

// exif-worker.js

// Import the exif-reader script:
importScripts('/js/with-worker/exifreader.js');

// Set up a messaging pipeline to send the Exif data to the `window`:
self.addEventListener('message', ({ data }) => {
  getExifDataFromImage(data).then(status => {
    self.postMessage(status);
  });
});

يعمل هذا الجزء من JavaScript على إعداد مسار المراسلة بحيث عندما ينقر المستخدم النموذج مع عنوان URL لملف JPEG، يصل عنوان URL إلى عامل الويب. من هنا، يعمل هذا الجزء التالي من التعليمة البرمجية على استخراج بيانات Exif الوصفية من ملف JPEG، تنشئ سلسلة HTML وترسل رمز HTML هذا مرة أخرى إلى window ليتم عرضه في النهاية المعروضة للمستخدم:

// Takes a blob to transform the image data into an `ArrayBuffer`:
// NOTE: these promises are simplified for readability, and don't include
// rejections on failures. Check out the complete web worker code:
// https://glitch.com/edit/#!/exif-worker?path=js%2Fwith-worker%2Fexif-worker.js%3A10%3A5
const readBlobAsArrayBuffer = blob => new Promise(resolve => {
  const reader = new FileReader();

  reader.onload = () => {
    resolve(reader.result);
  };

  reader.readAsArrayBuffer(blob);
});

// Takes the Exif metadata and converts it to a markup string to
// display in the Exif metadata viewer in the DOM:
const exifToMarkup = exif => Object.entries(exif).map(([exifNode, exifData]) => {
  return `
    <details>
      <summary>
        <h2>${exifNode}</h2>
      </summary>
      <p>${exifNode === 'base64' ? `<img src="data:image/jpeg;base64,${exifData}">` : typeof exifData.value === 'undefined' ? exifData : exifData.description || exifData.value}</p>
    </details>
  `;
}).join('');

// Fetches a partial image and gets its Exif data
const getExifDataFromImage = imageUrl => new Promise(resolve => {
  fetch(imageUrl, {
    headers: {
      // Use a range request to only download the first 64 KiB of an image.
      // This ensures bandwidth isn't wasted by downloading what may be a huge
      // JPEG file when all that's needed is the metadata.
      'Range': `bytes=0-${2 ** 10 * 64}`
    }
  }).then(response => {
    if (response.ok) {
      return response.clone().blob();
    }
  }).then(responseBlob => {
    readBlobAsArrayBuffer(responseBlob).then(arrayBuffer => {
      const tags = ExifReader.load(arrayBuffer, {
        expanded: true
      });

      resolve({
        status: true,
        message: Object.values(tags).map(tag => exifToMarkup(tag)).join('')
      });
    });
  });
});

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

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