पब्लिश होने की तारीख: 3 जुलाई, 2026
अगर आपने कभी किसी दस्तावेज़ एडिटर, स्प्रेडशीट ऐप्लिकेशन या ऐसे किसी ऐप्लिकेशन का इस्तेमाल किया है जहां क्लिपबोर्ड से कॉन्टेंट चिपकाना मुख्य इंटरैक्शन होता है, तो आपको उपयोगकर्ता की उम्मीद के बारे में पता होगा: चिपकाने की प्रोसेस तुरंत होनी चाहिए.
दुर्भाग्य से, कई मामलों में वेब ऐप्लिकेशन, क्लिपबोर्ड से ज़रूरत से ज़्यादा डेटा पढ़ते हैं. इससे कॉन्टेंट को चिपकाने में ज़्यादा समय लगता है, सीपीयू साइकल बर्बाद होती हैं, और ऐप्लिकेशन के लिए कभी भी ज़रूरी न होने वाले डेटा के लिए मेमोरी का इस्तेमाल होता है.
चुनिंदा फ़ॉर्मैट को पढ़ने की सुविधा, परफ़ॉर्मेंस से जुड़ी इस समस्या को ठीक करती है. इसके लिए, यह Async Clipboard API में बदलाव करती है, ताकि उपयोगकर्ताओं की उम्मीदों को बेहतर तरीके से पूरा किया जा सके. साथ ही, डेवलपर को वह जानकारी मिल सके जिसकी उन्हें ज़रूरत है. जैसे, सिर्फ़ उन फ़ॉर्मैट को पढ़ना जिनकी ऐप्लिकेशन को ज़रूरत है.
समस्या: सभी डेटा फ़ॉर्मैट को पहले से ही पढ़ लेना
जब कोई उपयोगकर्ता किसी ऐप्लिकेशन से कुछ कॉपी करता है, तो ऐप्लिकेशन आम तौर पर एक ही डेटा को सिस्टम क्लिपबोर्ड में कई फ़ॉर्मैट में सेव करता है. जैसे, सादा टेक्स्ट, एचटीएमएल, इमेज, और कभी-कभी कस्टम फ़ॉर्मैट. उदाहरण के लिए, Excel, Google Docs या Photoshop. जब उपयोगकर्ता क्लिपबोर्ड से डेटा चिपकाता है, तो डेटा को पढ़ने वाले वेब ऐप्लिकेशन को इन सभी फ़ॉर्मैट की ज़रूरत शायद ही कभी पड़ती है. स्प्रेडशीट एडिटर को एचटीएमएल की ज़रूरत पड़ सकती है. टेक्स्ट एडिटर, "सादे टेक्स्ट के रूप में चिपकाएं" कमांड को दिखाना चाहता है. कोड एडिटर को सिर्फ़ टेक्स्ट चाहिए होता है.
अब तक, navigator.clipboard.read() सिस्टम के क्लिपबोर्ड से, डेटा के हर उपलब्ध फ़ॉर्मैट को फ़ेच करता था. इसके बाद, डेटा को सुरक्षित करने की प्रोसेस शुरू होती थी. इसमें समय लग सकता था, खासकर बड़े एचटीएमएल या इमेज पेलोड के लिए. साथ ही, यह मेमोरी में बाइट सेव करता था. ऐसा उन फ़ॉर्मैट के लिए भी होता था जिनका इस्तेमाल ऐप्लिकेशन कभी नहीं करता था. इस्तेमाल नहीं किए गए पेलोड का साइज़ जितना बड़ा होगा, उपयोगकर्ता को उतना ही ज़्यादा इंतज़ार करना पड़ेगा. साथ ही, टैब उतनी ही ज़्यादा मेमोरी इस्तेमाल करेगा. ऐसा तब होगा, जब चिपकाने की सुविधा सबसे ज़्यादा मायने रखती है.
समाधान: सिर्फ़ गिनती करें, फिर मांग पर पढ़ें
Chrome और Edge 149 में, navigator.clipboard.read() तरीके से लौटाए गए ClipboardItem ऑब्जेक्ट सिर्फ़ यह बताते हैं कि क्लिपबोर्ड में क्या है. ये ऑब्जेक्ट, डेटा का ऐक्सेस तुरंत नहीं देते. किसी फ़ॉर्मैट के लिए, क्लिपबोर्ड से सिर्फ़ तब बाइट पढ़े जाते हैं, जब ClipboardItem.getType(mimeType) को कॉल किया जाता है.
एपीआई में कोई बदलाव नहीं किया गया है. आपने कल जो कोड लिखा था वह आज भी काम करता है. इससे आपको तुरंत ये फ़ायदे मिलते हैं:
// Enumerate the available MIME types.
// No payload is fetched yet.
const items = await navigator.clipboard.read();
for (const item of items) {
if (item.types.includes('text/html')) {
// Only read the HTML data.
// The data is fetched (and sanitized) here only.
const blob = await item.getType('text/html');
useThePastedHtml(await blob.text());
break;
}
// text/plain, image/png, or any other custom formats
// stored in the clipboard are never read.
}
यहां परफ़ॉर्मेंस का एक और फ़ायदा यह है कि कैश मेमोरी अपने-आप सेव हो जाती है. एक ही ClipboardItem पर getType('text/html') को दो बार कॉल करने पर, सिस्टम के क्लिपबोर्ड से सिर्फ़ एक बार डेटा पढ़ा जाता है. साथ ही, दूसरी बार कॉल करने पर, कैश मेमोरी में सेव किया गया Blob वापस मिलता है.
लाभ
लेटेंसी. navigator.clipboard.read()को कॉल करने पर जो काम होता था, जैसे कि प्रोसेस के बीच बाइट कॉपी करना, एचटीएमएल को सुरक्षित करना या इमेज डिकोड करना, अब सिर्फ़ उन फ़ॉर्मैट के लिए होता है जिनकी आपके ऐप्लिकेशन को ज़रूरत होती है. सिर्फ़ एक फ़ॉर्मैट को पढ़ने वाले ऐप्लिकेशन को सबसे ज़्यादा फ़ायदा मिलता है. जितने ज़्यादा फ़ॉर्मैट स्किप किए जाएंगे,
उतना ही ज़्यादा फ़ायदा होगा. एचटीएमएल को सबसे ज़्यादा फ़ायदा मिलता है, क्योंकि एचटीएमएल की जांच करना महंगा होता है.
मेमोरी. पहले, क्लिपबोर्ड में 50 एमबी की इमेज होने पर navigator.clipboard.read() को कॉल करने का मतलब था कि ClipboardItem के रिलीज़ होने तक, वेब पेज के रेंडरर मेमोरी में 50 एमबी का इस्तेमाल किया जाना चाहिए. भले ही, ऐप्लिकेशन को सिर्फ़ डेटा के text/plain वर्शन की ज़रूरत हो. अब, रेंडरर प्रोसेस में सिर्फ़ उन फ़ॉर्मैट के लिए मेमोरी का इस्तेमाल किया जाता है जिन्हें आपका ऐप्लिकेशन ClipboardItem.getType() को कॉल करते समय पढ़ता है. जिन ऐप्लिकेशन में कॉन्टेंट चिपकाने की सुविधा आम तौर पर इस्तेमाल की जाती है उनके लिए यह सुविधा बहुत काम की है. जैसे, दस्तावेज़ों को एडिट करने वाले ऐप्लिकेशन, ईमेल लिखने वाले ऐप्लिकेशन या डिज़ाइन टूल. इससे कॉन्टेंट चिपकाते समय मेमोरी का इस्तेमाल कम होता है. खास तौर पर, मल्टी-टैब सेशन में ऐसा होता है, जहां कई एडिटर एक साथ क्लिपबोर्ड को पढ़ सकते हैं.
ऑप्ट-इन करने की ज़रूरत नहीं है. वेब पर मौजूद हर साइट को ये फ़ायदे अपने-आप मिलते हैं. आपको कोड माइग्रेट करने या सुविधा का पता लगाने के लॉजिक के पीछे कोड को गेट करने की ज़रूरत नहीं है.
व्यवहार में होने वाले एक बदलाव के बारे में जानकारी
डेटा को बाद में पढ़ने से, व्यवहार में थोड़ा बदलाव होता है: ClipboardItem ऑब्जेक्ट अब क्लिपबोर्ड का फ़्रोज़न स्नैपशॉट नहीं है. यह navigator.clipboard.read() को कॉल करने के समय का स्नैपशॉट होता है.
जब read() को कॉल किया जाता है और यह ClipboardItem दिखाता है, तो यह आइटम सिर्फ़ सिस्टम क्लिपबोर्ड में मौजूद डेटा का लेज़ी हैंडल होता है.
अगर read() को कॉल करने और बाद में read() को कॉल करने के बीच क्लिपबोर्ड का कॉन्टेंट बदल जाता है, तो उस कॉल को InvalidStateError के साथ अस्वीकार कर दिया जाएगा.getType() ऐसा तब भी हो सकता है, जब आपने पहले उसी ClipboardItem पर किसी फ़ॉर्मैट को पढ़ लिया हो.
// Read from the clipboard.
const items = await navigator.clipboard.read();
// Get the first ClipboardItem.
const item = items[0];
// Actually fetch the data now, which works fine.
const text = await item.getType('text/plain');
// The user writes something new to the clipboard
// by copying from another app, or your own code writes to
// the clipboard again.
await navigator.clipboard.writeText('something new');
// Fetching the data from the earlier ClipboardItem
// rejects with InvalidStateError, because the contents
// of the clipboard changed.
const html = await item.getType('text/html');
ऐसा इसलिए होता है, क्योंकि अगर क्लिपबोर्ड में मौजूद डेटा को नहीं दिखाया जाता है, तो इससे भ्रम पैदा हो सकता है. साथ ही, इससे डीबग करने में मुश्किल आने वाली समस्याएं भी हो सकती हैं.
आम तौर पर, यह बदलाव ज़्यादातर कोड के लिए दिखता नहीं है. ऐसा इसलिए, क्योंकि ऐप्लिकेशन आम तौर पर एक ही पेस्ट हैंडलर में read() और getType() को एक के बाद एक कॉल करते हैं. हालांकि, आपको ऐसे मामलों पर नज़र रखनी चाहिए जहां आपके पास ऐसा कोड हो जो एसिंक बाउंड्री में ClipboardItem को बनाए रखता हो.
यहां एक उदाहरण दिया गया है, जिसमें इस बदलाव की वजह से समस्या हो सकती है: window पर ClipboardItem ऑब्जेक्ट को कैश मेमोरी में सेव करना, उन्हें क्लिपबोर्ड-इतिहास वाले यूज़र इंटरफ़ेस (यूआई) में दिखाना या getType() को कॉल करने से पहले उपयोगकर्ता के इंटरैक्शन का इंतज़ार करना. इस तरह की समस्या से बचने के लिए:
getType()कॉल कोtry / catchब्लॉक में रैप करें. साथ ही,InvalidStateErrorको ऐसे सिग्नल के तौर पर इस्तेमाल करें जिससे पता चले कि क्लिपबोर्ड बदल गया है और कोड को फिर से पढ़ना चाहिए.- अगर आपको क्लिपबोर्ड का डेटा सेव रखना है, तो
getType()करने के तुरंत बाद,Blobको अपने स्ट्रक्चर में कॉपी करें.ClipboardItemको लंबे समय तक स्टोर करने के लिए इस्तेमाल न करें. clipboardChangeइवेंट का इस्तेमाल करके, पुराने हैंडल को पहले से ही अमान्य कर दें.
मानक और ब्राउज़र के साथ काम करने की सुविधा
चुनिंदा फ़ॉर्मैट को पढ़ने की सुविधा, क्लिपबोर्ड एपीआई के स्पेसिफ़िकेशन में किया गया बदलाव है. इसे Web Editing Working Group और Microsoft Edge की वेब प्लैटफ़ॉर्म टीम ने लागू किया है.
Safari भी इस व्यवहार का समर्थन करता है. साथ ही, Firefox ने मानकों के हिसाब से काम करने और अलाइन करने के बारे में बताया है.
क्लिपबोर्ड एपीआई की परफ़ॉर्मेंस और इंटरऑपरेबिलिटी में सुधार किया गया है. हालांकि, यह सुधार ज़्यादा नहीं है. अब Chromium, एक ही मॉडल पर काम करेगा.