জাভাস্ক্রিপ্টে শেয়ার্ড ওয়ার্কার

জাভাস্ক্রিপ্টে শেয়ার্ড ওয়ার্কার

এই আর্টিকেলে জাভাস্ক্রিপ্টের Shared Worker ব্যাখ্যা করা হয়েছে।

আমরা Shared Worker-এর বুনিয়াদি থেকে শুরু করে ব্যবহারিক ব্যবহার পর্যন্ত সবকিছু ধাপে ধাপে ব্যাখ্যা করব।

YouTube Video

javascript-shared-worker.html
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <title>JavaScript &amp; HTML</title>
  6  <style>
  7    * {
  8        box-sizing: border-box;
  9    }
 10
 11    body {
 12        margin: 0;
 13        padding: 1em;
 14        padding-bottom: 10em;
 15        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 16        background-color: #f7f9fc;
 17        color: #333;
 18        line-height: 1.6;
 19    }
 20
 21    .container {
 22        max-width: 800px;
 23        margin: 0 auto;
 24        padding: 1em;
 25        background-color: #ffffff;
 26        border: 1px solid #ccc;
 27        border-radius: 10px;
 28        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 29    }
 30
 31    .container-flex {
 32        display: flex;
 33        flex-wrap: wrap;
 34        gap: 2em;
 35        max-width: 1000px;
 36        margin: 0 auto;
 37        padding: 1em;
 38        background-color: #ffffff;
 39        border: 1px solid #ccc;
 40        border-radius: 10px;
 41        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 42    }
 43
 44    .left-column, .right-column {
 45        flex: 1 1 200px;
 46        min-width: 200px;
 47    }
 48
 49    h1, h2 {
 50        font-size: 1.2rem;
 51        color: #007bff;
 52        margin-top: 0.5em;
 53        margin-bottom: 0.5em;
 54        border-left: 5px solid #007bff;
 55        padding-left: 0.6em;
 56        background-color: #e9f2ff;
 57    }
 58
 59    button {
 60        display: block;
 61        margin: 1em auto;
 62        padding: 0.75em 1.5em;
 63        font-size: 1rem;
 64        background-color: #007bff;
 65        color: white;
 66        border: none;
 67        border-radius: 6px;
 68        cursor: pointer;
 69        transition: background-color 0.3s ease;
 70    }
 71
 72    button:hover {
 73        background-color: #0056b3;
 74    }
 75
 76    #output {
 77        margin-top: 1em;
 78        background-color: #1e1e1e;
 79        color: #0f0;
 80        padding: 1em;
 81        border-radius: 8px;
 82        min-height: 200px;
 83        font-family: Consolas, monospace;
 84        font-size: 0.95rem;
 85        overflow-y: auto;
 86        white-space: pre-wrap;
 87    }
 88
 89    .highlight {
 90        outline: 3px solid #ffc107; /* yellow border */
 91        background-color: #fff8e1;  /* soft yellow background */
 92        transition: background-color 0.3s ease, outline 0.3s ease;
 93    }
 94
 95    .active {
 96        background-color: #28a745; /* green background */
 97        color: #fff;
 98        box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
 99        transition: background-color 0.3s ease, box-shadow 0.3s ease;
100    }
101  </style>
102</head>
103<body>
104    <div class="container">
105        <h1>JavaScript Console</h1>
106        <button id="executeBtn">Execute</button>
107        <div id="output"></div>
108    </div>
109
110    <script>
111        // Override console.log to display messages in the #output element
112        (function () {
113            // Override console.log
114            const originalLog = console.log;
115            console.log = function (...args) {
116                originalLog.apply(console, args);
117                const message = document.createElement('div');
118                message.textContent = args.map(String).join(' ');
119                output.appendChild(message);
120            };
121
122            // Override console.error
123            const originalError = console.error;
124            console.error = function (...args) {
125                originalError.apply(console, args);
126                const message = document.createElement('div');
127                message.textContent = args.map(String).join(' ');
128                message.style.color = 'red'; // Color error messages red
129                output.appendChild(message);
130            };
131        })();
132
133        document.getElementById('executeBtn').addEventListener('click', () => {
134            // Prevent multiple loads
135            if (document.getElementById('externalScript')) return;
136
137            const script = document.createElement('script');
138            script.src = 'javascript-shared-worker.js';
139            script.id = 'externalScript';
140            //script.onload = () => console.log('javascript-shared-worker.js loaded and executed.');
141            //script.onerror = () => console.log('Failed to load javascript-shared-worker.js.');
142            document.body.appendChild(script);
143        });
144    </script>
145</body>
146</html>

জাভাস্ক্রিপ্টে শেয়ার্ড ওয়ার্কার

Shared Worker কী?

Shared Worker হলো একটি ওয়ার্কার থ্রেড, যা একই উত্সের মধ্যে একাধিক পেজ (ট্যাব, উইন্ডো, আইফ্রেম ইত্যাদি) এর মধ্যে ভাগ করে নেওয়া যায়। একটি পৃষ্ঠা-নির্দিষ্ট Dedicated Worker-এর তুলনায়, প্রধান বৈশিষ্ট্য হল একটি ব্যাকগ্রাউন্ড প্রসেস একাধিক পৃষ্ঠার মধ্যে ভাগ করা যায়। পরিচিত কিছু ব্যবহারিক ক্ষেত্রের মধ্যে রয়েছে:।

  • আপনি একটি মাত্র WebSocket সংযোগ একাধিক ট্যাবে ভাগ করতে পারেন, ফলে সংযোগের সংখ্যা কমবে এবং পুনরায় সংযোগের কাজ কেন্দ্রীভূত হবে।
  • আপনি ট্যাবগুলোর মধ্যে স্টেট সিঙ্ক্রোনাইজ করতে পারেন (Pub/Sub বা স্টোরের জন্য কেন্দ্রীভূত ব্যবস্থাপনা)।
  • আপনি IndexedDB অপারেশন সিরিয়ালাইজ করতে পারেন, একাধিক একযোগে অ্যাক্সেসকে মধ্যস্থতা করে।
  • আপনি কম্পিউটেশন ব্যয়বহুল প্রসেসের দ্বৈত কার্যকরন প্রতিরোধ করতে পারেন

Shared Worker-এর ভূমিকা Service Worker-এর থেকে আলাদা। Service Worker প্রধানত নেটওয়ার্ক প্রক্সি হিসাবে কাজ করে, যখন Shared Worker মূলত পৃষ্ঠাগুলোর মধ্যে ভাগ করা যেকোনো গণনা বা অবস্থা ব্যবস্থাপনায় মনোযোগ দেয়।

বেসিক API এবং লাইফসাইকেল

তৈরি করা (মূল থ্রেড)

 1// main.js
 2// The second argument 'name' serves as an identifier to share the same SharedWorker
 3// if both the URL and name are the same.
 4const worker = new SharedWorker('/shared-worker.js', { name: 'app-core' });
 5
 6// Get the communication port (MessagePort) with this SharedWorker
 7const port = worker.port;
 8
 9// Receive messages with onmessage, send messages with postMessage
10port.onmessage = (ev) => {
11    console.log('From SharedWorker:', JSON.stringify(ev.data));
12};
13
14// When using onmessage, start() is not required
15// (start() is needed when using addEventListener instead)
16port.postMessage({ type: 'hello', from: location.pathname });
  • এই কোডটি দেখায় কীভাবে Shared Worker তৈরি ও তার পোর্টের মাধ্যমে বার্তা পাঠানো/গ্রহণ করা যায়।

Shared Worker-এর স্কোপের মধ্যে রিসিভার

 1// shared-worker.js
 2// SharedWorkerGlobalScope has an onconnect event,
 3// and a MessagePort is provided for each connection
 4const ports = new Set();
 5
 6onconnect = (e) => {
 7    const port = e.ports[0];
 8    ports.add(port);
 9
10    port.onmessage = (ev) => {
11        // Log the received message and send a reply back to the sender
12        console.log('From page:', ev.data);
13        port.postMessage({ type: 'ack', received: ev.data });
14    };
15
16    // For handling explicit disconnection from the page (via MessagePort.close())
17    port.onmessageerror = (err) => {
18        console.error('Message error:', err);
19    };
20
21    // Greeting immediately after connection
22    port.postMessage({ type: 'welcome', clientCount: ports.size });
23};
24
25// Explicit termination of the SharedWorker is usually unnecessary
26// (It will be garbage collected when all ports are closed)
  • এই কোডটি দেখায় কীভাবে Shared Worker-এর ভিতরে, প্রতিটি কানেকশনের জন্য একটি MessagePort গ্রহণ করা হয় এবং ক্লায়েন্টদের কাছ থেকে আসা বার্তা প্রক্রিয়া ও উত্তর দেয়।

Shared Worker-এর লাইফসাইকেল

Shared Worker প্রথম কানেকশন প্রতিষ্ঠিত হলে শুরু হয় এবং শেষ পোর্ট বন্ধ হলে বন্ধ হয়ে যেতে পারে। পেজ রিলোড বা বন্ধ হলে সংযোগগুলি বন্ধ হয়ে যায়, এবং প্রয়োজনে ওয়ার্কারটি পুনরায় তৈরি হয়।

Shared Worker হলো ব্রাউজারের ভিতরে "দীর্ঘস্থায়ী স্ক্রিপ্ট, যা শেয়ার করা যায়"। যদি আপনি Shared Worker-এর জীবনচক্রের প্রতি সতর্ক না হন, তাহলে রিসোর্স লিক, পুরানো অবস্থা বজায় থাকা, এবং অনিচ্ছাকৃত পুনরায় চালু হওয়ার মতো সমস্যা ঘটার সম্ভাবনা বেশি থাকে।

চেষ্টা করুন: ট্যাবগুলোর মধ্যে সম্প্রচার

এটি একটি ন্যূনতম ইমপ্লিমেন্টেশন, যেখানে একাধিক ট্যাব একই Shared Worker-এ কানেক্ট হয় এবং যে কোনো বার্তা পাঠানো হলে তা সব ট্যাবে সম্প্রচারিত হয়

main.js

 1const worker = new SharedWorker('/shared-worker.js', { name: 'bus' });
 2const port = worker.port;
 3
 4port.onmessage = (ev) => {
 5    const msg = ev.data;
 6    if (msg.type === 'message') {
 7        const li = document.createElement('li');
 8        li.textContent = `[${new Date(msg.at).toLocaleTimeString()}] ${msg.payload}`;
 9        document.querySelector('#messages').appendChild(li);
10    } else if (msg.type === 'ready') {
11        console.log(`Connected. clients=${msg.clients}`);
12    }
13};
14
15document.querySelector('#form').addEventListener('submit', (e) => {
16    e.preventDefault();
17    const input = document.querySelector('#text');
18    port.postMessage({ type: 'publish', payload: input.value });
19    input.value = '';
20});
21
22document.querySelector('#ping').addEventListener('click', () => {
23    port.postMessage({ type: 'ping' });
24});
  • এই কোডে একটি Shared Worker-এর সাথে সংযোগ স্থাপন, বার্তা গ্রহণ/প্রদর্শন, ফর্ম থেকে বার্তা পাঠানো এবং বাটন ক্লিক করে পিং পাঠানো ইমপ্লিমেন্ট করা হয়েছে।

shared-worker.js

 1// Minimal pub/sub bus in a SharedWorker
 2const subscribers = new Set();
 3
 4/** Broadcast to all connected ports */
 5function broadcast(message) {
 6    for (const port of subscribers) {
 7        try {
 8            port.postMessage(message);
 9        } catch (e) {
10            // Unsubscribe if sending fails, just in case
11            subscribers.delete(port);
12        }
13    }
14}
15
16onconnect = (e) => {
17    const port = e.ports[0];
18    subscribers.add(port);
19
20    port.onmessage = (ev) => {
21        const msg = ev.data;
22        if (msg && msg.type === 'publish') {
23            broadcast({ type: 'message', payload: msg.payload, at: Date.now() });
24        } else if (msg && msg.type === 'ping') {
25            port.postMessage({ type: 'pong', at: Date.now() });
26        }
27    };
28
29    port.postMessage({ type: 'ready', clients: subscribers.size });
30};
  • এই কোডটি Shared Worker-এর ভিতরে একটি সাধারণ pub/sub বৈশিষ্ট্য ইমপ্লিমেন্ট করেছে, যাতে একাধিক ক্লায়েন্টের মধ্যে বার্তা রিলে করা যায়।

index.html

 1<!doctype html>
 2<html>
 3    <body>
 4        <form id="form">
 5            <input id="text" placeholder="say something" />
 6            <button>Send</button>
 7        </form>
 8        <button id="ping">Ping</button>
 9        <ul id="messages"></ul>
10        <script src="/main.js" type="module"></script>
11    </body>
12</html>
  • আপনি যদি এই পৃষ্ঠাটি একাধিক ট্যাবে খোলেন, তবে যে কোনো ট্যাব থেকে পাঠানো বার্তা অন্যান্যদের কাছে জানানো হবে।

বার্তা ডিজাইন: রিকোয়েস্ট/রেসপন্স এবং কোরিলেশন আইডি

একাধিক ক্লায়েন্ট যখন Shared Worker-এর সাথে ইন্টার্যাক্ট করে, তখন আপনি প্রায়ই জানতে চান কোনো রেসপন্সটি কোন রিকোয়েস্টের সাথে সম্পর্কিত। সুতরাং, প্রতিক্রিয়াকে অনুরোধের সাথে যুক্ত করতে একটি সম্পর্ক আইডি সংযুক্ত করা হলো সাধারণ প্রথা।

main.js

 1function createClient(workerUrl, name) {
 2    const w = new SharedWorker(workerUrl, { name });
 3    const port = w.port;
 4    const pending = new Map(); // id -> {resolve,reject}
 5    let nextId = 1;
 6
 7    port.onmessage = (ev) => {
 8        const { id, ok, result, error } = ev.data || {};
 9        if (!id || !pending.has(id)) return;
10        const { resolve, reject } = pending.get(id);
11        pending.delete(id);
12        ok ? resolve(result) : reject(new Error(error));
13    };
14
15    function call(method, params) {
16        const id = nextId++;
17        return new Promise((resolve, reject) => {
18            pending.set(id, { resolve, reject });
19            port.postMessage({ id, method, params });
20        });
21    }
22
23    return { call };
24}
25
26// usage
27const client = createClient('/shared-worker.js', 'rpc');
28client.call('add', { a: 2, b: 3 }).then(console.log);   // -> 5
29client.call('sleep', { ms: 500 }).then(console.log);     // -> 'done'
  • এই কোড একটি সাধারণ RPC ক্লায়েন্ট ইমপ্লিমেন্ট করেছে, যা Shared Worker-এ অ্যাসিনক্রোনাস মেথড কল করতে পারে। এখানে একটি RPC সার্ভার (রিমোট প্রসিডিউর কল সার্ভার) বলতে এমন একটি সার্ভার বোঝায়, যা অন্য প্রোগ্রাম বা প্রসেস থেকে ফাংশন ও প্রসিডিউর ডাকার ব্যবস্থা প্রদান করে।
  • এই উদাহরণে, id শুধু বাড়ানো হয়েছে, তবে আপনি চাইলে UUID, এলোমেলো স্ট্রিং, বা টাইমস্ট্যাম্পের সাথে কাউন্টার যুক্ত করে একটি ইউনিক কী তৈরি করতে পারেন।

shared-worker.js

 1// A small request/response router with correlation ids
 2onconnect = (e) => {
 3    const port = e.ports[0];
 4
 5    port.onmessage = async (ev) => {
 6        const { id, method, params } = ev.data || {};
 7        try {
 8            let result;
 9            switch (method) {
10                case 'add':
11                    result = (params?.a ?? 0) + (params?.b ?? 0);
12                    break;
13                case 'sleep':
14                    await new Promise(r => setTimeout(r, params?.ms ?? 0));
15                    result = 'done';
16                    break;
17                default:
18                    throw new Error(`Unknown method: ${method}`);
19            }
20            port.postMessage({ id, ok: true, result });
21        } catch (err) {
22            port.postMessage({ id, ok: false, error: String(err) });
23        }
24    };
25};
  • এই কোডটি একটি সাধারণ RPC সার্ভার হিসাবে কাজ করে, যা method অনুযায়ী প্রসেসিং সম্পন্ন করে এবং অনুরোধ আইডিসহ ফলাফল ফেরত পাঠায়।

পরিচিত ব্যবহারিক প্যাটার্নসমূহ

Shared Worker ব্যবহারের কিছু পরিচিত ব্যবহারিক প্যাটার্ন আছে, যেমন:।

একক WebSocket মাল্টিপ্লেক্সিং (ট্যাবের মধ্যে ভাগ করা)

যদি প্রতিটি ট্যাব নিজের WebSocket সংযোগ খোলে, তাহলে এটি সার্ভারের লোড এবং সংযোগ সীমায় প্রভাব ফেলবে। Shared Worker-এ কেবল একটি WebSocket রাখুন, এবং প্রত্যেক ট্যাব ওই ওয়ার্কারের মাধ্যমে বার্তা পাঠানো/গ্রহণ করবে।

main.js

 1const w = new SharedWorker('/shared-worker.js', { name: 'ws' });
 2const port = w.port;
 3
 4port.onmessage = (ev) => {
 5    const msg = ev.data;
 6    if (msg.type === 'data') {
 7        console.log('Server says:', msg.payload);
 8    } else if (msg.type === 'socket') {
 9        console.log('WS state:', msg.state);
10    }
11};
12
13function send(payload) {
14    port.postMessage({ type: 'send', payload });
15}
  • এই কোডটি ওয়েবসকেট সার্ভারে বার্তা পাঠানো/গ্রহণ এবং Shared Worker এর মাধ্যমে সংযোগ স্থিতি বিজ্ঞপ্তি পাওয়ার প্রক্রিয়া ইমপ্লিমেন্ট করে।

shared-worker.js

 1let ws;
 2const ports = new Set();
 3
 4function ensureSocket() {
 5    if (ws && (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING)) {
 6        return;
 7    }
 8    ws = new WebSocket('wss://example.com/stream');
 9    ws.onopen = () => broadcast({ type: 'socket', state: 'open' });
10    ws.onclose = () => broadcast({ type: 'socket', state: 'closed' });
11    ws.onerror = (e) => broadcast({ type: 'socket', state: 'error', detail: String(e) });
12    ws.onmessage = (m) => broadcast({ type: 'data', payload: m.data });
13}
14
15function broadcast(msg) {
16    for (const p of ports) p.postMessage(msg);
17}
18
19onconnect = (e) => {
20    const port = e.ports[0];
21    ports.add(port);
22    ensureSocket();
23
24    port.onmessage = (ev) => {
25        const msg = ev.data;
26        if (msg?.type === 'send' && ws?.readyState === WebSocket.OPEN) {
27            ws.send(JSON.stringify(msg.payload));
28        }
29    };
30};
  • এই কোডটি Shared Worker-এর ভিতরে একটি ব্যবস্থা তৈরি করে, যাতে একক WebSocket সংযোগ ভাগ করা যায়, সংযোগের অবস্থা ও প্রাপ্ত ডাটা সকল ক্লায়েন্টের কাছে সম্প্রচারিত হয়, এবং প্রতিটি ক্লায়েন্টের প্রেরিত রিকোয়েস্ট ওয়েবসকেটের মাধ্যমে সার্ভারে পাঠানো হয়।

  • Shared Worker-এ পুনঃসংযোগ কৌশল ও অপাঠানো বার্তার কিউ কেন্দ্রীভূত করার মাধ্যমে, সব ট্যাবে আচরণ অভিন্ন থাকে

IndexedDB মধ্যস্থতা (সিরিয়ালাইজেশন)

একই ডাটাবেসে একাধিক ট্যাব একসাথে অ্যাক্সেস করলে, সমসাময়িক ট্রানজ্যাকশনের সংঘর্ষ বা লক ওয়েটিং এড়াতে চাইলে, আপনি সেগুলোকে Shared Worker-এ কিউ করে সিরিয়ালি প্রসেস করতে পারেন।

 1// db-worker.js (very simplified – error handling omitted)
 2let db;
 3async function openDB() {
 4    if (db) return db;
 5    db = await new Promise((resolve, reject) => {
 6        const req = indexedDB.open('appdb', 1);
 7        req.onupgradeneeded = () => req.result.createObjectStore('kv');
 8        req.onsuccess = () => resolve(req.result);
 9        req.onerror = () => reject(req.error);
10    });
11    return db;
12}
13
14async function put(key, value) {
15    const d = await openDB();
16    return new Promise((resolve, reject) => {
17        const tx = d.transaction('kv', 'readwrite');
18        tx.objectStore('kv').put(value, key);
19        tx.oncomplete = () => resolve(true);
20        tx.onerror = () => reject(tx.error);
21    });
22}
23
24async function get(key) {
25    const d = await openDB();
26    return new Promise((resolve, reject) => {
27        const tx = d.transaction('kv', 'readonly');
28        const req = tx.objectStore('kv').get(key);
29        req.onsuccess = () => resolve(req.result);
30        req.onerror = () => reject(req.error);
31    });
32}
33
34onconnect = (e) => {
35    const port = e.ports[0];
36    port.onmessage = async (ev) => {
37        const { id, op, key, value } = ev.data;
38        try {
39            const result = op === 'put' ? await put(key, value) : await get(key);
40            port.postMessage({ id, ok: true, result });
41        } catch (err) {
42            port.postMessage({ id, ok: false, error: String(err) });
43        }
44    };
45};
  • এই কোডে Shared Worker-এর মাধ্যমে IndexedDB-তে read/write অপারেশন কিউ করা হয়, যাতে একাধিক ট্যাব থেকে অ্যাক্সেস সিরিয়ালাইজ হয় এবং সংঘর্ষ বা লক কনটেনশন এড়ানো যায়।

মডুলারাইজেশন ও বান্ডলার টিপস

আপনি যদি Shared Worker স্ক্রিপ্টটি ES Module আকারে লেখেন, তবে পরিবেশ অনুযায়ী আচরণ ও সাপোর্ট ভিন্ন হতে পারে। অভ্যাসগতভাবে, নিচের যেকোনো একটি পদ্ধতি বেছে নেওয়া নিরাপদ:।

  • ক্লাসিক ওয়ার্কার ফরম্যাটে লিখুন, এবং প্রয়োজনে নির্ভরতা লোড করতে importScripts() ব্যবহার করুন।
  • আপনার বান্ডলারের ওয়ার্কার এন্ট্রি ফিচার ব্যবহার করুন (যেমন Vite / Webpack / esbuild ইত্যাদি), এবং বিল্ড সময়ে Shared Worker-এর জন্য আলাদা বান্ডল তৈরি করুন।

ত্রুটি ব্যবস্থাপনা, সংযোগ বিচ্ছিন্নতা শনাক্তকরণ ও নির্ভরযোগ্যতার জন্য টিপস

ত্রুটি ব্যবস্থাপনা ও নির্ভরযোগ্যতার জন্য নিচের বিষয়গুলো বিবেচনা করুন:।

  • সংযোগ স্থাপনের আগে পাঠানো হ্যান্ডলিং পোর্ট প্রস্তুত হওয়ার আগে আসা বার্তাগুলো কিউ করুন।

  • সংযোগ বিচ্ছিন্নতা শনাক্তকরণ MessagePort-এ কোনও স্ট্যান্ডার্ড onclose হ্যান্ডলার নেই। মূল দিকে, beforeunload-এর সময় port.postMessage এর মাধ্যমে {type: 'bye'} বার্তা পাঠান, অথবা প্রোটোকলে স্পষ্টভাবে উল্লেখ করুন যাতে worker পরিষ্কার হয়।

  • পুনরায় সংযোগ যখন একটি পৃষ্ঠা রিলোড হয় বা একটি ট্যাব পুনরায় খোলা হয়, তখন একটি নতুন পোর্ট তৈরি হয়। প্রাথমিক সিঙ্ক্রোনাইজেশন বার্তা প্রস্তুত করুন (একসাথে সম্পূর্ণ স্টেট পাঠাতে)।

  • ব্যাকপ্রেশার ভারী সম্প্রচারের সময়, থ্রটলিং/ডিবাউন্সিং অথবা স্ন্যাপশট পাঠানো-তে স্যুইচ করুন।

  • নিরাপত্তা Shared Worker মূলত একই উত্সের মধ্যে ভাগ করা হয়। ওয়ার্কারে যদি গোপনীয় ডেটা রাখেন, তাহলে কলিং সাইডে টোকেন বা অনুরূপ কোনো উপায়ে সাইড যাচাইকরণ ডিজাইন করুন।

কিভাবে যথাযথভাবে Dedicated Worker, Shared Worker, এবং Service Worker ব্যবহার করবেন

প্রত্যেক ধরনের Worker-এর নিম্নলিখিত বৈশিষ্ট্য রয়েছে:।

  • Dedicated Worker Dedicated Worker কেবলমাত্র একটি পৃষ্ঠার জন্য ব্যবহারের উদ্দেশ্যে তৈরি। এটি UI থেকে গণনার জন্য ১:১ পৃথকীকরণ সম্ভব করে তোলে।

  • Shared Worker Shared Worker একই উৎসের একাধিক পৃষ্ঠার মধ্যে ভাগ করা যেতে পারে। এটি ট্যাবের মধ্যে যোগাযোগ এবং একক সংযোগ ভাগাভাগি করার জন্য উপযুক্ত।

  • Service Worker Service Worker নেটওয়ার্ক প্রক্সি, ক্যাশিং, অফলাইনে কাজ, পুশ নোটিফিকেশন এবং পটভূমি সমন্বয়ের জন্য ব্যবহার করা যেতে পারে। এর শক্তি হল ফেচ রিকোয়েস্ট আটকে দেয়ার ক্ষমতা

একটি সাধারণ নিয়ম: ট্যাবগুলোর মধ্যে 'তথ্য ভাগাভাগি ও যেকোনো প্রসেসিংয়ের' জন্য Shared Worker, 'নেটওয়ার্ক নিয়ন্ত্রণের' জন্য Service Worker, এবং শুধু UI থেকে ভারী প্রসেসিং আলাদা করতে চাইলে Dedicated Worker ব্যবহার করুন।

সাধারণ ভুলসমূহ

Shared Worker ব্যবহার করার সময় নিচের বিষয়গুলো সম্পর্কে সতর্ক থাকতে হবে।

  • start() ডাকতে ভুলে যাওয়া বা অপ্রয়োজনীয় আহ্বান port.addEventListener('message', ...) ব্যবহারের সময় আপনাকে অবশ্যই port.start() কল করতে হবে। যদি আপনি port.onmessage = ... ব্যবহার করেন, তাহলে এটি অনাবশ্যক।

  • অbeheerিত সম্প্রচার ট্যাবের সংখ্যা বাড়লে লোডও বাড়ে। পার্থক্যমূলক ডেলিভারি বা সাবস্ক্রিপশন টপিকস (বিষয় অনুযায়ী ফিল্টার করে) ব্যবহার করে লোড কমানো যায়।

  • বস্তু কপির খরচ postMessage ডাটা ডুপ্লিকেট করে। বড় ডাটার জন্য, এটিকে Transferable (যেমন ArrayBuffer) হিসেবে পাঠানো বা shared memory (SharedArrayBuffer) এবং Atomics একসাথে ব্যবহার করা বিবেচনা করুন।

  • আয়ু ও পুনরায় সূচনা শেষ ক্লায়েন্ট সংযোগ বিচ্ছিন্ন করলে Shared Worker বন্ধ হয়ে যেতে পারে। প্রথম সংযোগ এবং পুনরায় চালু করার ক্ষেত্রে পার্শ্বপ্রতিক্রিয়া ও বাগ এড়াতে উপযুক্তভাবে সূচনা ডিজাইন করুন।

সারসংক্ষেপ

  • Shared Worker হল একাধিক পৃষ্ঠার মধ্যে ভাগ করা দীর্ঘস্থায়ী কাস্টম লজিক বাস্তবায়নের স্থান।
  • মেসেজ সংক্রান্ত চুক্তি (টাইপ/প্রোটোকল) পরিষ্কার করুন এবং correlation IDs সংযুক্ত করে আপনার অনুরোধ/প্রতিক্রিয়ার ডিজাইন আরও মজবুত করুন।
  • যেসব প্রক্রিয়া সব ট্যাবে একত্রে কাজ করলে ভালো হয়, যেমন WebSocket সংযোগ মাল্টিপ্লেক্সিং বা IndexedDB-তে ধারাবাহিক অ্যাক্সেস—এসবের জন্য এটি আদর্শ।
  • বান্ডলার, টাইপ ডেফিনিশন কিংবা পুনঃসংযোগের মত সূক্ষ্ম বিষয়াবলী সমন্বয় করলে রক্ষণাবেক্ষণ ও ব্যবহারকারীর অভিজ্ঞতা অনেক উন্নত হবে

আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।

YouTube Video