در آخرین ماژول، مروری بر وب کارگران ارائه شد. کارگران وب می توانند پاسخگویی ورودی را با جابجایی جاوا اسکریپت از رشته اصلی برای جدا کردن رشته های وب کارگر بهبود بخشند، که می تواند به بهبود تعامل وب سایت شما با رنگ بعدی (INP) در زمانی که کاری دارید که نیازی به دسترسی مستقیم به رشته اصلی ندارد، کمک کند. با این حال، یک مرور کلی به تنهایی کافی نیست، و در این ماژول، یک مورد استفاده مشخص برای یک وب کارگر ارائه شده است.
یکی از این موارد استفاده می تواند وب سایتی باشد که باید ابرداده Exif را از یک تصویر حذف کند – این مفهوم چندان دور از ذهنی نیست. در واقع، وبسایتهایی مانند فلیکر به کاربران راهی برای مشاهده ابردادههای Exif ارائه میکنند تا جزئیات فنی در مورد تصاویری که میزبانی میکنند، مانند عمق رنگ، ساخت و مدل دوربین و سایر دادهها را بیاموزند.
با این حال، منطق واکشی یک تصویر، تبدیل آن به یک ArrayBuffer
، و استخراج فراداده Exif میتواند به طور بالقوه گران باشد اگر به طور کامل در رشته اصلی انجام شود. خوشبختانه، حوزه وب کارگر اجازه می دهد تا این کار خارج از موضوع اصلی انجام شود. سپس، با استفاده از خط لوله پیامرسانی وبکارگر، فراداده Exif به عنوان یک رشته HTML به رشته اصلی ارسال میشود و به کاربر نمایش داده میشود.
موضوع اصلی بدون وب کارگر چگونه به نظر می رسد
ابتدا، مشاهده کنید که وقتی این کار را بدون وبکار انجام میدهیم، موضوع اصلی چگونه به نظر میرسد. برای این کار مراحل زیر را انجام دهید:
- یک تب جدید در کروم باز کنید و DevTools آن را باز کنید.
- پانل عملکرد را باز کنید.
- به https://exif-worker.glitch.me/without-worker.html بروید.
- در پانل عملکرد، روی Record در گوشه سمت راست بالای صفحه DevTools کلیک کنید.
- این پیوند تصویر - یا یکی دیگر از موارد انتخابی شما که حاوی فراداده Exif است - را در فیلد قرار دهید و روی Get that JPEG کلیک کنید! دکمه
- هنگامی که رابط با فراداده Exif پر شد، دوباره روی Record کلیک کنید تا ضبط متوقف شود.
توجه داشته باشید که - به غیر از رشتههای دیگری که ممکن است وجود داشته باشند، مانند رشتههای شطرنجساز و غیره - همه چیز در برنامه در رشته اصلی رخ میدهد. در موضوع اصلی، موارد زیر رخ می دهد:
- فرم ورودی را می گیرد و یک درخواست
fetch
ارسال می کند تا قسمت اولیه تصویر حاوی فراداده Exif را دریافت کند. - داده های تصویر به یک
ArrayBuffer
تبدیل می شوند. - اسکریپت
exif-reader
برای استخراج فراداده Exif از تصویر استفاده می شود. - ابرداده خراشیده می شود تا یک رشته HTML ساخته شود، که سپس نمایشگر فراداده را پر می کند.
اکنون آن را با اجرای همان رفتار مقایسه کنید - اما با استفاده از یک وب کارگر!
موضوع اصلی با یک وب کارگر چگونه است
اکنون که مشاهده کردید که برای استخراج فراداده Exif از یک فایل JPEG در رشته اصلی چگونه به نظر می رسند، نگاهی به شکل ظاهری زمانی که یک وب کارگر در ترکیب است بیندازید:
- یک برگه دیگر در کروم باز کنید و DevTools آن را باز کنید.
- پانل عملکرد را باز کنید.
- به https://exif-worker.glitch.me/with-worker.html بروید.
- در پانل عملکرد، روی دکمه ضبط در گوشه سمت راست بالای صفحه DevTools کلیک کنید.
- این پیوند تصویر را در فیلد قرار دهید و روی Get that JPEG کلیک کنید! دکمه
- هنگامی که رابط با فراداده Exif پر شد، دوباره روی دکمه ضبط کلیک کنید تا ضبط متوقف شود.
این قدرت یک وب کارگر است. به جای انجام همه کارها در رشته اصلی، همه چیز به جز پر کردن نمایشگر ابرداده با HTML در یک رشته جداگانه انجام می شود. این بدان معنی است که رشته اصلی برای انجام کارهای دیگر آزاد می شود.
شاید بزرگترین مزیت در اینجا این باشد که بر خلاف نسخهای از این برنامه که از وبکارگر استفاده نمیکند، اسکریپت exif-reader
روی رشته اصلی بارگذاری نمیشود، بلکه روی رشته وب کارگر بارگذاری میشود. این بدان معنی است که هزینه دانلود، تجزیه و کامپایل اسکریپت exif-reader
خارج از موضوع اصلی است.
اکنون به کد web worker که همه اینها را ممکن میسازد شیرجه بزنید!
نگاهی به کد وب کارگر
دیدن تفاوتی که یک وبکارگر ایجاد میکند کافی نیست، بلکه به درک - حداقل در این مورد - کمک میکند که آن کد چگونه به نظر میرسد تا بدانید در محدوده وبکارگر چه چیزی ممکن است.
با کد رشته اصلی که باید قبل از اینکه وبکارگر بتواند تصویر را وارد کند، شروع کنید:
// 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 تصویر به وبکارگر تنظیم میکند. از آنجا، کد web worker با دستور 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);
});
});
این بیت از جاوا اسکریپت خط لوله پیام را تنظیم می کند به طوری که وقتی کاربر فرم را با 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
و پردازش پاسخها، پردازش مقادیر زیادی از دادهها بدون مسدود کردن رشته اصلی - و این فقط برای شروع است.
هنگامی که عملکرد برنامه های کاربردی وب خود را بهبود می بخشید، شروع به فکر کردن به هر کاری کنید که می توان به طور منطقی در زمینه وب کارگر انجام داد. این دستاوردها می تواند قابل توجه باشد و می تواند منجر به تجربه کاربری بهتری برای وب سایت شما شود.