کار با Web Workerها در React
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 5 دقیقه

کار با Web Workerها در React

بیشتر توسعه دهندگان رابط کاربری با چالش فریز یا متوقف شدن UI در هنگام اجرای یک قطعه کد روبرو شده‌اند. حالتی که در آن شما قصد دارید تا قسمتی از کدهای‌تان را اجرا کنید و رابط کاربری در این حالت برای چند لحظه از کار افتاده یا اصطلاحا Freeze کرده است. اگر که با پروژه‌های زیادی روبرو بوده باشید مطمئنا با این مشکل روبرو شده‌اید. اما راه‌ چاره چیست؟ در این مقاله از سایت آموزش برنامه نویسی راکت قصد داریم تا این موضوع را باهم بررسی کنیم. 

در دنیای کتابخانه React.js برای اینکه بتوانیم پردازش‌های سنگین و CPU-Intensive را در پس زمینه اجرا کنیم، می‌توانیم از Web Workerها کمک بگیریم. اما قبل از اینکه با روش پیاده‌سازی این تکنیک آشنا شویم بیایید با اینکه Web Worker دقیقا چیست آشنا شویم.

Web Worker چیست؟

در دنیای جاوا اسکریپت Web Workerها امکاناتی هستند که به ما این قابلیت را می‌دهند تا اسکریپت‌هایی را در پس زمینه برنامه و جدا از رشته اصلی یا Main Thread که مربوط به صفحات وب می‌شود، اجرا کنیم. مزیت اینکار در این است که شما می‌توانید یکسری پردازش‌ها را موازی با پردازش‌هایی که در لایه رابط کاربری اتفاق می‌افتد، اجرا کنید. به همین دلیل، در فرایند پردازش رابط کاربری مشکلی پیش نخواهد آمد. Web Workerها زمانی که قصد انجام پردازش‌های سنگین و زمان‌بر را داشته باشیم بسیار حیاتی خواهند بود و اجازه نمی‌دهند که رابط کاربری ما از انجام کارهای عادی خود باز بماند.

سه استفاده کلی از وب ورکرها

سه حالت کلی برای استفاده از Web Workerها وجود دارد که در زیر این سه مورد را به شما معرفی کرده‌ایم:

  • محاسبات پیچیده: وب ورکرها برای زمانی که بخواهیم حجم عظیمی از محاسبات ریاضی یا منطقی را پیش ببریم می‌توانند مورد استفاده قرار بگیرند. پردازش داده‌ها یکی دیگر از محاسبات پیچیده‌ای هستند که با استفاده از وب ورکرها به سادگی امکان پذیر خواهند بود.
  • کار با حجم عظیمی از داده: زمانی که شما با حجم بزرگی از فایل‌ها و داده‌ها کار می‌کنید برای پردازش، مدیریت و انجام کارهای I/O نیاز دارید که از رشته اصلی خارج شده و در یک رشته دیگر به صورت موازی این کارها را انجام دهید. Web Workerها در این حالت نیز به شما کمک خواهند کرد.
  • سرویس‌های پس زمینه: وب ورکرها برای اجرا سرویس‌های پس زمینه یا Background Serviceها نیز مفید هستند. مواردی مانند همگام‌سازی یا سینک کردن داده‌ها و نوتیفیکشن‌های پس زمینه.

پیاده‌سازی و استفاده از وب ورکرها در React

برای پیاده‌سازی وب ورکرها در ری‌اکت ابتدا نیاز است یک پروژه React را ایجاد کنید و بعد با استفاده از کتابخانه Faker، رکوردهای فیک جدیدی را ایجاد کنید. در این مثال ما ۲۵۰۰ کاربر را ایجاد کرده‌ایم.

import { faker } from '@faker-js/faker';

export function fetchUsers() {
    const users = [];

    for (let i = 0; i < 25000; i++) {
        let id = i + 1;
        let name = faker.person.fullName();
        let email = faker.internet.email();
        let joinedOn = faker.date.recent();
        let commentCount = faker.number.int({ min: 0, max: 100 });
        let user = {
            id,
            name,
            email,
            joinedOn,
            commentCount
        };
        users.push(user);
    }
    return Promise.resolve(users);
}

نکته: Faker یک کتابخانه جاوا اسکریپتی برای ایجاد حجم عظیمی از داده برای تست اپلیکیشن است.

حال برای اینکه یک حالت از پردازش سنگین را بوجود بیاوریم، قصد داریم تا تمام این رکوردها را براساس فیلد “commentCound” مرتب‌سازی بکنیم. برای اینکار نیاز است تا از ویژگی‌های وب ورکر استفاده کنیم.

ابتدا دو فایل با نام‌های app.worker.js و WebWorker.js را در دایرکتوری src ایجاد می‌کنیم. در داخل فایل app.worker.js یک تابع جدید ایجاد کرده و در آن از یک Event Listener با هدف دنبال کردن یک message استفاده می‌کنیم. این Message زمانی triggered می‌شود که در رابط کاربری متغیرهای users و type فراخوانی شوند. در نهایت براساس type (صعودی یا نزولی) انتخاب شده، متد postMessage برگشت داده خواهد شد. به قطعه کد زیر نگاه کنید:

export default () => {
  self.addEventListener('message', e => { // eslint-disable-line no-restricted-globals
      if (!e) return;
      let { users, type } = e.data;

      if(type === "asc") {
        users = users.sort((a, b) => a.commentCount - b.commentCount);
      } else {
        users = users.sort((a, b) => b.commentCount - a.commentCount);
      }

      postMessage(users);
  })
}

حال در فایل WebWorker.js یک کلاس را export می‌کنیم. به قطعه کد زیر نگاه کنید:

export default class WebWorker {
    constructor(worker) {
        const code = worker.toString();
        const blob = new Blob(['('+code+')()']);
        return new Worker(URL.createObjectURL(blob));
    }
}

کاری که در قطعه کد بالا انجام داده‌ایم این است که ورکری که در فایل قبلی ایجاد کرده‌ایم را به یک Object URL تغییر می‌دهد. حال نیاز است که این وب ورکر را به رابط کاربری متصل کنیم. ابتدا باید هر دو فایل را به پروژه React خود اضافه کنیم:

import worker from './app.worker.js';
import WebWorker from './WebWorker';

حال نیاز است که از WebWorker یک نمونه ایجاد کنیم:

const webWorker = new WebWorker(worker);

حال نیاز است که ما با استفاده از متد postMessage که خروجی تابع اولیه‌مان بود، متغیر users و type را معلوم کنیم. همانطور که در قطعه کد زیر مشاهده می‌کنید مقدار پیشفرض type برابر با حالت Ascending است.

webWorker.postMessage({ users, type: "asc"});

حال ما از یک Event Listener برای message استفاده می‌کنیم تا داده‌های مرتب شده از وب ورکر را دریافت کنیم.

webWorker.addEventListener('message', (event) => {
            const sortedList = event.data;

            setUsers(sortedList);
});

همین کار را برای مرتب سازی از نوع Descending نیز می‌توانیم انجام دهیم:

webWorker.postMessage({ users, type: "desc"});
        webWorker.addEventListener('message', (event) => {
            const sortedList = event.data;

            setUsers(sortedList);
        });

حال همانطور که می‌بینید وب ورکر ما به خوبی کار می‌کند. اما به عنوان یک نکته مهم این را فراموش نکنید که در زمان جداسازی کامپوننت، وب ورکر را قطع یا اصطلاحا Terminate کنید. برای اینکار از قطعه کد زیر استفاده کنید.

return () => {
            webWorker.terminate()
        }

در پایان

وب ورکرها یکی از مهمترین ویژگی‌های دنیا وب هستند که امکان انجام پردازش‌های سنگین را بدون درگیر کردن رابط کاربری به ما می‌دهند. استفاده کردن از این ویژگی در دنیای امروزی که معمولا اپلیکیشن‌ها با داده‌های مختلفی سر و کار دارند بسیار می‌تواند مفید باشد. همچنین شما میتوانید آموزش react را در راکت ببینید و بیشتر با موضوعات و زیبایی های این زبان آشنا شوید. 

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
3.67 از 3 رای

/@arastoo
ارسطو عباسی
کارشناس تولید و بهینه‌سازی محتوا

کپی رایتر، یوایکس رایتر، متخصص سئو محتوا و… عناوینی هستن که می‌تونم حرفه‌ام رو باهاشون خلاصه کنم اما جدای از این موارد، کتاب نوشتم، پادکست ضبط کردم، مارکتینگ محتوا انجام دادم و خلاصه تجربیات تا بخوایید در زمینه کلمات کسب کردم.

دیدگاه و پرسش

برای ارسال دیدگاه لازم است وارد شده یا ثبت‌نام کنید ورود یا ثبت‌نام

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

ارسطو عباسی

کارشناس تولید و بهینه‌سازی محتوا