Prompt और लागू होने वाले परिदृश्य
एक same-origin एनालिटिक्स ऐप की तीन स्वतंत्र आवश्यकताएं हैं:
- यूज़र द्वारा चुनी गई 200 MiB CSV को स्थानीय रूप से पार्स करना, जबकि इनपुट और रेंडरिंग रिस्पॉन्सिव बने रहें।
- जब तक कम से कम एक टैब खुला रहता है, तब तक टैब के बीच एक WebSocket और इन-मेमोरी सब्सक्रिप्शन स्थिति साझा करना।
- ऑफ़लाइन होने पर ऐप शेल और अंतिम सफल रिपोर्ट खोलना, एक सेव को कतारबद्ध (queue) करना, और कनेक्टिविटी लौटने के बाद रीट्राय करना।
प्रत्येक आवश्यकता के लिए Dedicated Worker, SharedWorker, और Service Worker में से चुनें। ओनरशिप, लाइफ़टाइम, कम्युनिकेशन, पर्सिस्टेंस, कैंसिलेशन और फ़ेल्योर हैंडलिंग, ब्राउज़र फ़ॉलबैक, सुरक्षा सीमाएं (security boundaries), और वैलिडेशन की व्याख्या करें।
200 MiB फ़ाइल, सिंगल WebSocket, और ऑफ़लाइन सेव इंटरव्यू के अनुमान हैं, सार्वभौमिक उत्पाद लक्ष्य नहीं। यह प्रश्न सीनियर फ़्रंटएंड, Web प्लेटफ़ॉर्म, और फ़्रंटएंड आर्किटेक्चर भूमिकाओं के लिए उपयुक्त है। इसका मुख्य कौशल ब्राउज़र निष्पादन और Web प्लेटफ़ॉर्म चयन है, इसलिए श्रेणी frontend है।
इंटरव्यूअर क्या मूल्यांकन करता है
पहला, क्या उम्मीदवार प्रत्येक बैकग्राउंड थ्रेड को केवल Web Worker कहने के बजाय इस आधार पर चयन कर सकता है कि काम का मालिक कौन है, इसे कितने समय तक जीवित रहना चाहिए, और यह किन पेजों को प्रभावित करता है? एक मजबूत उत्तर पेज-स्वामित्व वाली गणना को Dedicated Worker को, अस्थायी same-origin मल्टी-पेज स्थिति को SharedWorker को, और स्कोप्ड नेटवर्क प्रॉक्सीइंग, कैशिंग, और इवेंट-ड्रिवेन बैकग्राउंड कार्य को Service Worker को सौंपता है।
दूसरा, क्या उम्मीदवार थ्रेडिंग को पर्सिस्टेंस से अलग कर सकता है? कोड को मुख्य थ्रेड से हटाने से CPU, मेमोरी या I/O अपने आप कम नहीं होते हैं। SharedWorker मेमोरी ड्युरेबल स्टेट (टिकाऊ स्थिति) नहीं है। एक ब्राउज़र इवेंट्स के बीच Service Worker को रोक सकता है, इसलिए पेंडिंग कार्य IndexedDB जैसे ड्युरेबल स्टोरेज में होना चाहिए।
तीसरा, क्या उम्मीदवार मैसेजिंग लागत का आकलन कर सकता है? Structured cloning आमतौर पर डेटा को कॉपी करता है। एक ArrayBuffer को ट्रांसफ़र किया जा सकता है ताकि इसका ओनरशिप बिना किसी अन्य बाइट-दर-बाइट कॉपी के स्थानांतरित हो जाए, लेकिन प्रेषक का बफ़र डिटेच हो जाता है। बड़े CSV हैंडलिंग के लिए चंकिंग, प्रगति, बैकप्रेशर और कैंसिलेशन की भी आवश्यकता होती है।
चौथा, क्या उम्मीदवार एक सही फ़ॉलबैक प्रदान कर सकता है? SharedWorker वर्तमान ब्राउज़र रिलीज़ में Baseline 2026 तक पहुँच गया है, लेकिन पुराने डिवाइस और कुछ कार्यान्वयन इसका समर्थन नहीं कर सकते हैं। Background Sync अभी भी Baseline नहीं है। शुद्धता किसी एक वैकल्पिक API पर निर्भर नहीं हो सकती।
पांचवां, क्या उम्मीदवार लाइफ़साइकिल विफलताओं का परीक्षण कर सकता है? केवल एक हैप्पी-पाथ क्लिक-थ्रू पर्याप्त नहीं है। रिफ्रेश, अंतिम टैब बंद करना, Service Worker अपडेट, ऑफ़लाइन रीस्टार्ट, डुप्लिकेट सिंक इवेंट, कैश संदूषण (cache contamination), और पुराने-ब्राउज़र फ़ॉलबैक सभी मायने रखते हैं।
पहले स्पष्ट करने योग्य प्रश्न
- क्या CSV पार्सिंग कभी-कभार होती है या निरंतर? एकमुश्त कार्य मांग पर एक Dedicated Worker बना सकता है। निरंतर समवर्ती कार्य के लिए प्रति फ़ाइल एक नया थ्रेड बनाने के बजाय एक सीमित वर्कर पूल और कतार की आवश्यकता होती है।
- क्या संपूर्ण इनपुट मेमोरी में होना चाहिए? जब पार्सर इसका समर्थन करता है तो स्ट्रीमिंग या चंक्ड इनपुट को प्राथमिकता दें। यदि पूरे
ArrayBufferको एक साथ स्थानांतरित करना होगा, तो रॉ बाइट्स, डिकोड किए गए स्ट्रिंग्स, पार्स किए गए मानों और इंडेक्स के लिए अलग से बजट बनाएं। - क्या सभी टैब पूरी तरह से same-origin हैं? SharedWorker को समान स्कीम, होस्ट और पोर्ट की आवश्यकता होती है। सबडोमेन, थर्ड-पार्टी iframes, या भिन्न डेवलपमेंट पोर्ट कम्युनिकेशन डिज़ाइन को बदल देते हैं।
- क्या एक WebSocket केवल एक ऑप्टिमाइज़ेशन है या शुद्धता की बाध्यता? यदि यह केवल कनेक्शन बचाता है, तो प्रति-टैब कनेक्शन एक मान्य फ़ॉलबैक है। यदि सर्वर केवल एक सत्र की अनुमति देता है, तो फ़ॉलबैक को BroadcastChannel, लीडर चुनाव (leader election), लीज और स्प्लिट-ब्रेन रिकवरी की आवश्यकता होती है।
- क्या ऑफ़लाइन सेव स्वचालित रूप से रीट्राय हो सकता है? संवेदनशील या परस्पर विरोधी ऑपरेशनों के लिए पेज लौटने के बाद यूज़र कन्फ़र्मेशन की आवश्यकता हो सकती है। स्वचालित रीट्राय के लिए एक idempotency की, ड्युरेबल स्टेट और सीमित बैकऑफ़ की आवश्यकता होती है।
- कौन से पुराने ब्राउज़र और प्राइवेसी मोड दायरे में हैं? वह उत्तर SharedWorker, Background Sync, स्टोरेज कोटा और Service Worker व्यवहार के लिए फ़ीचर-डिटेक्शन और फ़ॉलबैक सीमा निर्धारित करता है।
30-सेकंड उत्तर रूपरेखा
"मैं आवश्यकताओं को ओनरशिप और लाइफ़टाइम के आधार पर विभाजित करूँगा। 200 MiB CSV वर्तमान पेज के स्वामित्व वाला CPU-गहन कार्य है, इसलिए मैं एक Dedicated Worker का उपयोग करूँगा, चंक्स में पार्स करूँगा, प्रगति रिपोर्ट करूँगा, ओनरशिप स्थानांतरित होने पर ArrayBuffer ट्रांसफ़र करूँगा, और सहयोगात्मक रूप से रद्द करूँगा या वर्कर को समाप्त करूँगा। मैं एक same-origin क्रॉस-टैब WebSocket को SharedWorker में रखूँगा और प्रत्येक पेज को MessagePort के माध्यम से सब्सक्राइब करने दूँगा, फ़ीचर डिटेक्शन और BroadcastChannel प्लस लीडर चुनाव या स्वीकार्य होने पर प्रति टैब एक कनेक्शन के फ़ॉलबैक के साथ। मैं ऑफ़लाइन शेल, रिपोर्ट कैश, और बाद में रीट्राय के लिए Service Worker का उपयोग करूँगा क्योंकि यह स्कोप्ड अनुरोधों को इंटरसेप्ट कर सकता है और बैकग्राउंड इवेंट्स को संभाल सकता है। कतार idempotency कीज़ के साथ IndexedDB में जाती है। Background Sync के बिना, पेज इसे स्टार्टअप, फ़ोरग्राउंडिंग या पुनः कनेक्शन पर फ़्लश करता है। मैं अंतिम-टैब बंद होने, ऑफ़लाइन रीस्टार्ट, डुप्लिकेट सिंक, और Service Worker अपडेट का परीक्षण करूँगा।"
चरण-दर-चरण गहन विश्लेषण
चरण 1: ओनरशिप, स्कोप और लाइफ़टाइम के आधार पर चुनें
| आवश्यकता | चयन | स्वामी और कम्युनिकेशन | मुख्य विफलता सीमा |
|---|---|---|---|
| वर्तमान पेज के लिए एक बड़ा CSV पार्स करना | Dedicated Worker | क्रिएटिंग पेज; postMessage | पेज बंद होना, कैंसिलेशन, मेमोरी पीक |
| Same-origin टैब में एक कनेक्शन साझा करना | SharedWorker | Same-origin पेज; प्रति पेज एक MessagePort | अंतिम संदर्भ बंद होना, पुराने ब्राउज़र में समर्थन की कमी |
| ऑफ़लाइन शेल, नेटवर्क प्रॉक्सी, बाद में सिंक | Service Worker | रजिस्टर्ड ओरिजिन और पाथ स्कोप; इवेंट्स और क्लाइंट संदेश | अपडेट वेटिंग, इवेंट्स के बीच समाप्ति, वैकल्पिक API अनुपलब्ध |
तीनों में से कोई भी सीधे DOM में हेरफेर नहीं कर सकता है। Dedicated Worker और SharedWorker पेजों द्वारा आवश्यक JavaScript कार्य चलाते हैं। Service Worker एक इवेंट-ड्रिवेन नेटवर्क प्रॉक्सी है जो एक ओरिजिन और पाथ के विरुद्ध पंजीकृत होता है। यह समर्थित ब्राउज़रों में fetch, कैशिंग, Push, और बैकग्राउंड सिंक को संभाल सकता है, लेकिन यह ऐसे CSV पार्स के लिए एक खराब स्थान है जिसे मिनटों तक लगातार चलना पड़ता है।
चरण 2: Dedicated Worker में 200 MiB CSV पार्स को अलग करें
मांग पर Dedicated Worker बनाएं क्योंकि यह कार्य केवल वर्तमान पेज की सेवा करता है। मुख्य थ्रेड फ़ाइल चयन, प्रगति UI, और परिणाम रेंडरिंग का मालिक है। वर्कर डिकोडिंग, टोकनाइज़ेशन, टाइप इनफेरेंस और एग्रीगेशन का मालिक है। इसमें कोई DOM एक्सेस नहीं है, इसलिए यह संदेशों के माध्यम से परिणाम लौटाता है।
यह इंटरफ़ेस स्केच पार्सर और एरर प्रकारों को छोड़ देता है। chunkBytes वर्कर को आंतरिक रूप से 4 MiB बैचों में आगे बढ़ने के लिए कहता है; इसका मतलब यह नहीं है कि मुख्य थ्रेड एक और कॉपी बनाता है:
const parser = new Worker(
new URL("./csv-parser.worker.js", import.meta.url),
{ type: "module" },
);
const jobId = crypto.randomUUID();
const buffer = await file.arrayBuffer();
parser.postMessage(
{ type: "parse", jobId, buffer, chunkBytes: 4 * 1024 * 1024 },
[buffer],
);
parser.onmessage = ({ data }) => {
if (data.jobId !== jobId) return;
if (data.type === "progress") renderProgress(data.rows);
if (data.type === "done") renderReport(data.summary);
};
cancelButton.onclick = () => {
parser.postMessage({ type: "cancel", jobId });
};कैंसिलेशन सहयोगात्मक या बलपूर्वक हो सकता है। पार्स लूप चंक सीमाओं पर एक कैंसिलेशन फ़्लैग की जांच करता है, अस्थायी वस्तुओं को रिलीज़ करता है, और अंतिम स्थिति की रिपोर्ट करता है। यदि वर्कर हैंग हो जाता है या पार्सर यील्ड नहीं कर सकता है, तो terminate() इसे रोक देता है, लेकिन उस वर्कर के अंदर का हर काम खो जाता है। इसलिए लंबे समय तक चलने वाले मल्टी-फ़ाइल प्रोसेसर को एक अविभाजित शेयर्ड वर्कर के बजाय जॉब आइसोलेशन की आवश्यकता होती है।
चरण 3: कॉपी करने और पीक मेमोरी के लिए डिज़ाइन करें
साधारण postMessage स्ट्रक्चर्ड क्लोनिंग का उपयोग करता है। एक सरलीकृत धारणा के तहत जहां प्रेषक और रिसीवर दोनों में 200 MiB ArrayBuffer मौजूद है, केवल रॉ बाइट्स ही लगभग 400 MiB घेरते हैं। इसमें File बैकिंग स्टोर, डिकोड किए गए स्ट्रिंग्स, रो ऑब्जेक्ट्स, इंडेक्स और गारबेज-कलेक्शन हेडरूम शामिल नहीं हैं। यह एक इंटरव्यू डेरिवेशन है, कोई ब्राउज़र मेमोरी गारंटी नहीं।
ArrayBuffer को ट्रांसफ़र सूची में रखने से इसका मेमोरी संसाधन वर्कर में स्थानांतरित हो जाता है और प्रेषक का बफ़र अलग (detach) हो जाता है, जिससे वह बाइट कॉपी बच जाती है। यदि पेज को अभी भी मूल की आवश्यकता है और ओनरशिप को डिज़ाइन नहीं किया गया है, तो इसे ट्रांसफ़र न करें। एक सुरक्षित लार्ज-इनपुट पाथ Blob.stream() या स्लाइस को पढ़ता है, छोटे चंक्स भेजता है, और वृद्धिशील (incremental) आंकड़े प्राप्त करता है। मुख्य थ्रेड इन-फ़्लाइट चंक्स को सीमित करता है और पावती (acknowledgment) के बाद ही अगला चंक भेजता है, जो बैकप्रेशर बनाता है।
शेयर्ड मेमोरी डिफ़ॉल्ट शॉर्टकट नहीं है। SharedArrayBuffer को क्रॉस-ओरिजिन आइसोलेशन की आवश्यकता होती है और यह एटॉमिक्स, डेटा रेस और सख्त डिप्लॉयमेंट सुरक्षा का परिचय देता है। जब तक माप यह न दिखाए कि सामान्य संदेश और ट्रांसफ़रेबल ऑब्जेक्ट्स बाधा (bottleneck) हैं, तब तक उस जटिलता को न जोड़ें।
चरण 4: Same-origin मल्टी-टैब कनेक्शन को SharedWorker में रखें
SharedWorker "कम से कम एक same-origin पेज के जुड़े रहने तक एक साझा इंस्टेंस बनाए रखने" से मेल खाता है। प्रत्येक टैब एक ही URL पर समान नामित वर्कर खोलता है और अपने स्वयं के MessagePort पर सब्सक्रिप्शन पंजीकृत करता है। वर्कर WebSocket, पोर्ट्स का एक सेट, और एक इन-मेमोरी सब्सक्रिप्शन मैप का मालिक होता है, फिर सर्वर संदेशों को संबंधित पोर्ट्स पर रूट करता है।
const socketHub = new SharedWorker(
new URL("./socket-hub.shared-worker.js", import.meta.url),
{ type: "module", name: "analytics-socket-hub" },
);
socketHub.port.start();
socketHub.port.postMessage({ type: "subscribe", reportId });
socketHub.port.onmessage = ({ data }) => applyLiveUpdate(data);
window.addEventListener("pagehide", () => {
socketHub.port.postMessage({ type: "disconnect", reportId });
socketHub.port.close();
});केवल सटीक same-origin संदर्भ ही SharedWorker तक पहुंच सकते हैं। यह तब तक जीवित रह सकता है जब तक कोई खुला पेज संदर्भ रखता है; अंतिम संदर्भ बंद होने के बाद, यह एक स्थायी बैकग्राउंड सेवा नहीं है। कनेक्शन टूटना, ब्राउज़र बंद होना या वर्कर क्रैश सब्सक्रिप्शन मैप को मिटा सकता है। सर्वर कर्सर को पर्सिस्ट करें जिन्हें जीवित रहना चाहिए, या प्रत्येक पेज को अपने सब्सक्रिप्शन को फिर से घोषित करने दें।
चरण 5: SharedWorker को एक वास्तविक फ़ॉलबैक दें
SharedWorker का फ़ीचर-डिटेक्शन करें। इसके बिना, टैब BroadcastChannel पर हार्टबीट और इवेंट्स का आदान-प्रदान कर सकते हैं, जबकि Web Locks या एक एक्सपायरिंग स्टोरेज लीज WebSocket का स्वामित्व लेने के लिए एक लीडर का चुनाव करती है। लीडर के बंद होने के बाद अन्य टैब एक प्रतिस्थापन चुनते हैं। सर्वर सेशन और इवेंट ID द्वारा डुप्लिकेट को हटाता है, जबकि क्लाइंट स्प्लिट-ब्रेन क्षति को सीमित करने के लिए मोनोटोनिक युग (monotonic epoch) का उपयोग करके पुराने लीडर के संदेशों को अस्वीकार करते हैं।
वह फ़ॉलबैक SharedWorker की तुलना में काफी अधिक जटिल है। यदि एक कनेक्शन केवल लागत ऑप्टिमाइज़ेशन है, तो सबसे सरल सही फ़ॉलबैक सर्वर-साइड आइडम्पोटेंसी और कनेक्शन सीमाओं के साथ प्रति टैब एक WebSocket है। चुनाव, लीज नवीनीकरण, विफलता का पता लगाने और फ़ॉल्ट इंजेक्शन का निर्माण केवल तभी करें जब एक सख्त सर्वर बाध्यता के लिए एक कनेक्शन की आवश्यकता हो।
चरण 6: ऑफ़लाइन व्यवहार और रीट्राय के लिए Service Worker का उपयोग करें
Service Worker एक ओरिजिन और पाथ स्कोप के विरुद्ध पंजीकृत होता है और नियंत्रित पेजों से अनुरोधों को इंटरसेप्ट कर सकता है। ऐप शेल वर्ज़न्ड प्रीकैशिंग या कैश-फ़र्स्ट के अनुकूल होता है। नवीनतम रिपोर्ट अक्सर नेटवर्क-फ़र्स्ट के अनुकूल होती है: एक सफल नेटवर्क प्रतिक्रिया पर Cache Storage को अपडेट करें और विफलता पर अंतिम सफल कैश्ड प्रतिक्रिया लौटाएं। यूज़र की सेव कतार को IndexedDB में रखें, Cache Storage या Service Worker ग्लोबल वेरिएबल में नहीं।
यह अभी भी एक इंटरफ़ेस स्केच है। प्रोडक्शन कोड को कैशेबल URL को अनुमति सूची में डालना चाहिए, प्रतिक्रियाओं को मान्य करना चाहिए, कैश को वर्ज़न करना चाहिए, और "queued" दिखाने से पहले सेव को IndexedDB में लिखना चाहिए:
navigator.serviceWorker.register("/sw.js", { scope: "/" });
// sw.js
self.addEventListener("install", (event) => {
event.waitUntil(cacheAppShell());
});
self.addEventListener("fetch", (event) => {
const url = new URL(event.request.url);
if (url.pathname.startsWith("/reports/")) {
event.respondWith(networkFirstReport(event.request));
}
});
self.addEventListener("sync", (event) => {
if (event.tag === "retry-report-saves") {
event.waitUntil(flushIndexedDbQueue());
}
});Background Sync केवल कुछ ब्राउज़रों में उपलब्ध है। यदि पंजीकरण विफल हो जाता है या API अनुपस्थित है, तो पेज शुरू होने, फ़ोरग्राउंड में लौटने या online इवेंट प्राप्त होने पर उसी कतार फ़्लशर को कॉल करें। कनेक्टिविटी इवेंट्स रीट्राय ट्रिगर हैं, सफलता का प्रमाण नहीं; केवल सर्वर प्रतिक्रिया ही पूर्णता की पुष्टि करती है। प्रत्येक सेव एक idempotency की, प्रयास गणना और अगले रीट्राय समय को संग्रहीत करता है। विरोध (conflicts) हमेशा के लिए अधिलेखित (overwrite) होने के बजाय एक समीक्षा स्थिति में प्रवेश करते हैं।
चरण 7: Service Worker लाइफ़टाइम और अपडेट संभालें
एक Service Worker डाउनलोड, इंस्टॉलेशन, वेटिंग और एक्टिवेशन के बाद ही पेजों को नियंत्रित करता है। पहले पंजीकरण के बाद, वर्तमान दस्तावेज़ को नियंत्रित होने से पहले आमतौर पर दूसरे नेविगेशन की आवश्यकता होती है। एक नया संस्करण स्थापित हो सकता है और पुराने संस्करण का उपयोग करने वाले पेजों के बंद होने की प्रतीक्षा कर सकता है। skipWaiting() और clients.claim() तेजी से नियंत्रण ले सकते हैं, लेकिन प्रोटोकॉल भिन्न होने पर एक नए वर्कर के साथ जोड़ा गया पुराना पेज टूट सकता है। उसी के अनुसार संदेश और कैश स्कीमा को वर्ज़न करें।
ब्राउज़र इवेंट्स के बीच एक वर्कर को समाप्त कर सकता है और अगले इवेंट के लिए इसे फिर से शुरू कर सकता है। event.waitUntil() वर्तमान इवेंट के Promise से जुड़े लाइफ़टाइम को बढ़ाता है; यह एक रेजिडेंट प्रोसेस नहीं बनाता है। कतार, प्रयास गणना और idempotency की को पर्सिस्ट करें। सिंक प्रोसेसिंग को किसी भी रिकॉर्ड से फिर से शुरू होना चाहिए और सुरक्षित रूप से उसी अनुरोध को दो बार चलाना चाहिए।
Service Workers को एक सुरक्षित संदर्भ की आवश्यकता होती है। HTTPS प्रोडक्शन आवश्यकता है, जबकि localhost एक डेवलपमेंट अपवाद है। डिफ़ॉल्ट स्कोप स्क्रिप्ट पाथ द्वारा विवश होता है। CSP worker-src, यूज़र-संवेदनशील कैश सामग्री, लॉगआउट आइसोलेशन, और क्रॉस-ओरिजिन अनुरोधों के लिए CORS और क्रेडेंशियल व्यवहार को भी सत्यापित करें।
चरण 8: विफलता मैट्रिक्स के साथ मान्य करें
Dedicated Worker का 1 MiB और 200 MiB फ़ाइलों, विकृत इनपुट और कैंसिलेशन के साथ परीक्षण करें। मेन-थ्रेड लॉन्ग टास्क, इनपुट डिले, पार्स थ्रूपुट, पीक मेमोरी, और कैंसिलेशन के बाद रिलीज़ समय रिकॉर्ड करें। स्ट्रक्चर्ड क्लोन, ट्रांसफ़रेबल और चंक्ड वेरिएंट की तुलना करें, फिर मापी गई बाधा को चुनें।
दो समवर्ती सदस्यताओं, लीडर पेज को बंद करने, अंतिम पेज को बंद करने, नेटवर्क फ़्लैप्स, वर्कर एरर्स, और SharedWorker के बिना ब्राउज़र के साथ SharedWorker का परीक्षण करें। स्वीकृति जांचों में वास्तविक सर्वर कनेक्शन गणना, कोई अप्रत्याशित संदेश अंतराल या डुप्लिकेट नहीं, पुनः कनेक्ट होने के बाद कर्सर निरंतरता, और एक फ़ॉलबैक शामिल है जो शुद्धता को बनाए रखता है।
पहली विज़िट, नियंत्रित पुनरीक्षण, ऑफ़लाइन रिफ्रेश, कैश समाप्ति, प्रतीक्षा कर रहे अपडेट, फ़ोर्स्ड ब्राउज़र शटडाउन, डुप्लिकेट sync, समाप्त स्टोरेज कोटा, और अनुपलब्ध Background Sync पर Service Worker का परीक्षण करें। यह साबित करने के लिए कि कम से कम एक बार के प्रयास डुप्लिकेट राइट्स नहीं बनाते हैं, सेव एंडपॉइंट पर idempotency कीज़ का उपयोग करें। सत्यापित करें कि कैश्ड निजी डेटा उपयोगकर्ताओं के बीच क्रॉस नहीं हो सकता है।
उच्च-गुणवत्ता वाला नमूना उत्तर
"मैं इस बात से शुरुआत करूँगा कि कार्य का मालिक कौन है, इसे कितने समय तक जीवित रहना चाहिए, और क्या यह नेटवर्क को प्रॉक्सी करता है। 200 MiB CSV केवल वर्तमान पेज की सेवा करता है और CPU-गहन है, इसलिए मैं एक Dedicated Worker का उपयोग करूँगा। मुख्य थ्रेड फ़ाइल चयन और UI को संभालता है; वर्कर चंक्स को पार्स करता है, प्रगति की रिपोर्ट करता है, और चंक्स के बीच कैंसिलेशन की जांच करता है। सामान्य मैसेजिंग स्ट्रक्चर्ड क्लोन का उपयोग करती है। यदि दोनों पक्षों पर एक पूर्ण 200 MiB बफ़र मौजूद है, तो इंटरव्यू धारणा केवल रॉ बाइट्स को लगभग 400 MiB मानती है, इसलिए मैं एक ट्रांसफ़रेबल ArrayBuffer को बेंचमार्क करूँगा जो ओनरशिप को स्थानांतरित करता है या इन-फ़्लाइट सीमित संख्या के साथ चंक्स को स्ट्रीम करता है।
मैं एक क्रॉस-टैब WebSocket को SharedWorker में रखूँगा। प्रत्येक पेज पूरी तरह से same-origin होना चाहिए और अपने MessagePort के माध्यम से सब्सक्रिप्शन को फिर से घोषित करता है। वर्कर केवल पुनर्निर्माण योग्य कनेक्शन और रूटिंग स्थिति संग्रहीत करता है। यह पर्सिस्टेंस नहीं है; अंतिम पेज बंद होने, ब्राउज़र से बाहर निकलने या वर्कर के क्रैश होने के बाद स्थिति गायब हो सकती है। मैं इसका फ़ीचर-डिटेक्शन करूँगा। यदि एक कनेक्शन केवल एक ऑप्टिमाइज़ेशन है, तो फ़ॉलबैक प्रति टैब एक कनेक्शन है। यदि यह एक सख्त बाध्यता है, तो मैं स्प्लिट ब्रेन और डुप्लिकेट्स के लिए युगों और इवेंट IDs के साथ BroadcastChannel प्लस लीज-आधारित चुनाव का उपयोग करूँगा।
मैं ऑफ़लाइन शेल, नवीनतम रिपोर्ट, और बाद में सेव के लिए Service Worker का उपयोग करूँगा। यह स्कोप के भीतर अनुरोधों को इंटरसेप्ट करता है: शेल के लिए वर्ज़न्ड प्रीकैशिंग और रिपोर्ट के लिए कैश फ़ॉलबैक के साथ नेटवर्क-फ़र्स्ट। बैकग्राउंड सिंक पंजीकृत होने से पहले सेव को एक idempotency की के साथ IndexedDB में लिखा जाता है। Background Sync के बिना, स्टार्टअप, फ़ोरग्राउंडिंग, या पुनः कनेक्ट होना उसी फ़्लशर को लागू करता है। चूंकि Service Worker इवेंट्स के बीच रुक सकता है, इसलिए कतार कभी भी केवल एक ग्लोबल में नहीं रहती है; प्रत्येक रन ड्युरेबल स्टेट को पुनर्प्राप्त करता है और वर्तमान कार्य को waitUntil() के साथ जोड़ता है।
अंत में, मैं मेन-थ्रेड लॉन्ग टास्क और मेमोरी, वास्तविक WebSocket कनेक्शन गणना और पुनः कनेक्ट व्यवहार, ऑफ़लाइन रीस्टार्ट और डुप्लिकेट सिंक, साथ ही Service Worker अपडेट वेटिंग, पुराने-ब्राउज़र फ़ॉलबैक, प्रति-यूज़र कैश आइसोलेशन, और HTTPS तथा CSP सीमाओं को मान्य करूँगा।"
सामान्य गलतियाँ
- Service Worker को लंबे समय तक चलने वाले कंप्यूट थ्रेड के रूप में उपयोग करना → ब्राउज़र इसे इवेंट्स के बीच या लंबे काम के दौरान समाप्त कर सकता है → पेज गणना के लिए Dedicated Worker का उपयोग करें और इवेंट-ड्रिवेन नेटवर्क कार्य के लिए Service Worker आरक्षित करें।
- मेमोरी को मापे बिना
postMessageके साथ 200 MiB ऑब्जेक्ट भेजना → स्ट्रक्चर्ड क्लोन और पार्स किए गए परिणाम एक बड़े पीक पर सह-अस्तित्व में हो सकते हैं → ट्रांसफ़रेबल, चंक्ड और स्ट्रीमिंग पाथ्स की तुलना करें और पीक को मापें। - यह मान लेना कि कोई भी वर्कर एक रिस्पॉन्सिव ऐप की गारंटी देता है → CPU, गारबेज कलेक्शन, और सीरियलाइज़ेशन में अभी भी समय लगता है → मेन-थ्रेड लॉन्ग टास्क, थ्रूपुट और संदेश बैच आकार को मापें।
- SharedWorker मेमोरी को विश्वसनीय स्थिति के रूप में मानना → अंतिम संदर्भ बंद होने या ब्राउज़र से बाहर निकलने के बाद यह गायब हो सकती है → केवल पुनर्निर्माण योग्य रनटाइम स्थिति रखें और महत्वपूर्ण कर्सर और कतारों को पर्सिस्ट करें।
- सटीक same-origin आवश्यकताओं की अनदेखी करना → एक भिन्न स्कीम, होस्ट या पोर्ट इसे साझा नहीं कर सकता है → क्लाइंट-साइड समन्वय चुनने से पहले ओरिजिन सीमाओं का मानचित्रण करें।
- जब भी SharedWorker अनुपलब्ध हो, एक जटिल चुनाव प्रणाली की नकल करना → व्यवसाय को शुद्धता की आवश्यकता हो सकती है, न कि ठीक एक कनेक्शन की → तय करें कि क्या कनेक्शन गणना एक सख्त बाध्यता है और अन्यथा प्रति टैब फ़ॉलबैक करें।
- Service Worker ग्लोबल में एक ऑफ़लाइन कतार रखना → एक वर्कर रीस्टार्ट नौकरियों को खो देता है → पहले IndexedDB लिखें और एक रीप्ले-सुरक्षित फ़्लशर लागू करें।
- केवल Background Sync पर निर्भर होना → यह अभी भी प्रत्येक प्रमुख ब्राउज़र द्वारा समर्थित Baseline सुविधा नहीं है → स्टार्टअप, फ़ोरग्राउंडिंग और पुनः कनेक्शन पर भी रीट्राय करें।
- प्रत्येक अपडेट को तुरंत नियंत्रण लेने के लिए बाध्य करना → एक पुराने पेज और नए वर्कर में असंगत प्रोटोकॉल हो सकते हैं → वेटिंग को छोड़ने का चयन करने से पहले संदेशों, कैश और माइग्रेशन को वर्ज़न करें।
- प्रत्येक सफल प्रतिक्रिया को कैश करना → निजी डेटा खातों में बना रह सकता है या गलत तरीके से पुन: उपयोग किया जा सकता है → एक URL अनुमति सूची, प्रति-यूज़र अलगाव, लॉगआउट क्लीनअप, और प्रतिक्रिया सत्यापन का उपयोग करें।
फ़ॉलो-अप प्रश्न और प्रतिक्रियाएं
फ़ॉलो-अप 1: क्या बदलता है जब CSV 2 GiB तक बढ़ जाता है और मोबाइल मेमोरी अपर्याप्त होती है?
पूर्ण इनपुट के लिए file.arrayBuffer() को कॉल करना बंद करें। Blob.stream() या slice() चंक्स पढ़ें, डिकोड सीमाओं के पार एक आंशिक पंक्ति बनाए रखें, और वर्कर को समुच्चय (aggregates) या स्तंभ बैच वापस करने दें। इन-फ़्लाइट चंक्स को सीमित करें और बैकप्रेशर के लिए पावती की आवश्यकता रखें। कैंसिलेशन पॉइंट प्रदर्शित करें। यदि उत्पाद को प्रत्येक पंक्ति को बनाए रखना होगा, तो संपूर्ण ऑब्जेक्ट ग्राफ़ को JavaScript हीप पर रखने के बजाय IndexedDB या खंडित फ़ाइलों में स्पिल करें और परिणामों को पेज करें। एक डिवाइस-विशिष्ट सीमा और एक स्पष्ट अस्वीकृति पाथ जोड़ें।
फ़ॉलो-अप 2: क्या होगा यदि विभिन्न सबडोमेन पर पेजों को ठीक एक WebSocket साझा करना होगा?
SharedWorker सटीक ओरिजिन सीमाओं को पार नहीं कर सकता है। एक विकल्प एक नियंत्रित ओरिजिन है जो लाइव कनेक्शन का मालिक है और सख्त targetOrigin, प्रेषक और स्कीमा सत्यापन के साथ एक ऑडिटेड iframe संदेश ब्रिज को उजागर करता है। दूसरा विकल्प सिंगल-कनेक्शन समन्वय को सर्वर पर स्थानांतरित करना है जबकि प्रत्येक पेज एक स्वतंत्र क्लाइंट कनेक्शन रखता है। पहला सुरक्षा और उपलब्धता को जोड़ता है; दूसरे में अधिक सर्वर कनेक्शन खर्च होते हैं। same-origin नीति को बायपास करने का प्रयास करने के बजाय वास्तविक कठिन बाधा से चुनें।
फ़ॉलो-अप 3: SharedWorker Baseline 2026 है, तो फ़ॉलबैक क्यों रखें?
उत्पाद के ब्राउज़र मैट्रिक्स का उपयोग करें। Baseline 2026 वर्तमान ब्राउज़र रिलीज़ में एक नई सामान्य क्षमता का वर्णन करता है; यह प्रत्येक पुराने डिवाइस, स्थिर एंटरप्राइज़ संस्करण, प्राइवेसी मोड या एम्बेडेड वातावरण को कवर नहीं करता है। फ़ीचर डिटेक्शन सस्ता है। फ़ॉलबैक के रूप में प्रति-टैब कनेक्शन से शुरुआत करें और चुनाव का निर्माण केवल तभी करें जब कोई कठिन कनेक्शन बाधा इसे उचित ठहराती हो।
फ़ॉलो-अप 4: जब Background Sync सेव को दोहराता है तो आप डुप्लिकेट राइट्स को कैसे रोकते हैं?
क्लाइंट व्यावसायिक ऑपरेशन के लिए एक स्थिर idempotency की बनाता है। कतार कम से कम इसके पेलोड, की, प्रयास गणना और अगले रीट्राय समय को संग्रहीत करती है। सर्वर विशिष्टता लागू करता है या यूज़र और की द्वारा परिणाम संग्रहीत करता है, डुप्लिकेट के लिए मूल परिणाम लौटाता है। क्लाइंट पुष्टि के बाद ही कतार आइटम को हटाता है। टाइमआउट का अर्थ है अज्ञात परिणाम और उसी की के साथ रीट्राय, कभी भी नई की नहीं। व्यावसायिक-संस्करण विरोध मौन अधिलेखन के बजाय समीक्षा में चले जाते हैं।
फ़ॉलो-अप 5: एक नया Service Worker स्थापित किया गया है, लेकिन उपयोगकर्ता अनिश्चित काल के लिए एक पुराना पेज खुला रखते हैं। आप क्या करते हैं?
नियंत्रित पेजों को सूचित करें कि एक अपडेट तैयार है और यूज़र को एक सुरक्षित बिंदु पर रीफ्रेश करने दें। एक सुरक्षा फ़िक्स केवल तभी skipWaiting() और clients.claim() का उपयोग कर सकता है जब पुराने और नए पेज वर्कर के संदेश प्रोटोकॉल के साथ संगत रहें और कैश तथा IndexedDB माइग्रेशन रीएंट्रेंट हों। रिलीज़ परीक्षणों में नए वर्कर के साथ एक पुराने पेज का परीक्षण किया जाना चाहिए। जब अनुकूलता की गारंटी नहीं दी जा सकती है, तो केवल तत्काल एक्टिवेशन के लिए अनुकूलन करने के बजाय प्रतीक्षा चरण को बनाए रखें।
फ़ॉलो-अप 6: टैब में WebSocket साझा करने के लिए Service Worker का भी उपयोग क्यों नहीं करते?
Service Worker का लाइफ़टाइम इवेंट-ड्रिवेन होता है, और ब्राउज़र निष्क्रिय होने पर इसे रोक सकता है। एक WebSocket को निरंतर कनेक्शन और इन-मेमोरी सत्र की आवश्यकता होती है, जो उस मॉडल के साथ संघर्ष करता है। जब तक पेज संदर्भ बने रहते हैं, SharedWorker एक बेहतर मालिक होता है। यदि लक्षित ब्राउज़र में SharedWorker की कमी है और एक कनेक्शन अनिवार्य है, तो यह मानने के बजाय कि Service Worker निवासी रहता है, क्रॉस-टैब चुनाव का उपयोग करें या सर्वर आर्किटेक्चर बदलें।