ऑफ़स्क्रीन कैनवस—वेब वर्कर के साथ अपनी कैनवस प्रोसेस में तेज़ी लाएं

Tim Dresser

कैनवस, स्क्रीन पर सभी तरह के ग्राफ़िक बनाने का एक लोकप्रिय तरीका है. साथ ही, यह WebGL की दुनिया में प्रवेश करने का एक एंट्री पॉइंट भी है. इसका इस्तेमाल आकार, इमेज बनाने, ऐनिमेशन चलाने या वीडियो कॉन्टेंट दिखाने और प्रोसेस करने के लिए किया जा सकता है. इसका इस्तेमाल अक्सर, मीडिया से भरपूर वेब ऐप्लिकेशन और ऑनलाइन गेम में बेहतर उपयोगकर्ता अनुभव देने के लिए किया जाता है.

इस पर स्क्रिप्ट लिखी जा सकती है. इसका मतलब है कि कैनवस पर खींचा गया कॉन्टेंट, प्रोग्राम के हिसाब से बनाया जा सकता है. उदाहरण के लिए, JavaScript में. इससे कैनवस को ज़्यादा सुविधाएं मिलती हैं.

साथ ही, आधुनिक वेबसाइटों में स्क्रिप्ट का लागू होना, उपयोगकर्ताओं को जवाब देने में लगने वाले समय से जुड़ी समस्याओं का सबसे ज़्यादा सामान्य सोर्स है. कैनवस लॉजिक और रेंडरिंग, उपयोगकर्ता इंटरैक्शन के साथ-साथ एक ही थ्रेड पर होती है. इसलिए, ऐनिमेशन में शामिल (कभी-कभी भारी) गणना, ऐप्लिकेशन की असल और अनुमानित परफ़ॉर्मेंस पर असर डाल सकती है.

सौभाग्य से, OffscreenCanvas इस खतरे का जवाब है.

ब्राउज़र के इस्तेमाल से जुड़ी सहायता

  • Chrome: 69.
  • Edge: 79.
  • Firefox: 105.
  • Safari: 16.4.

सोर्स

पहले, कैनवस पर ड्रॉइंग करने की सुविधाएं <canvas> एलिमेंट से जुड़ी होती थीं. इसका मतलब है कि यह सीधे तौर पर डीओएम पर निर्भर थी. जैसा कि नाम से पता चलता है, OffscreenCanvas, DOM और Canvas API को स्क्रीन से हटाकर, उन्हें अलग कर देता है.

अलग करने की इस सुविधा की मदद से, OffscreenCanvas को पूरी तरह से DOM से अलग किया गया है. इसलिए, यह सामान्य कैनवस की तुलना में तेज़ी से काम करता है, क्योंकि दोनों के बीच सिंक नहीं होता.

इसके अलावा, वेब वर्कर्स में भी इसका इस्तेमाल किया जा सकता है, भले ही कोई डोम उपलब्ध न हो. इससे, अलग-अलग तरह के दिलचस्प इस्तेमाल के उदाहरण मिलते हैं.

वर्कर्स में OffscreenCanvas का इस्तेमाल करना

वर्कर्स, वेब पर थ्रेड के तौर पर काम करते हैं. इनकी मदद से, बैकग्राउंड में टास्क चलाए जा सकते हैं.

अपनी कुछ स्क्रिप्टिंग को वर्कर्स पर ले जाने से, आपके ऐप्लिकेशन को मुख्य थ्रेड पर उपयोगकर्ता के लिए ज़रूरी टास्क करने के लिए ज़्यादा समय मिलता है. OffscreenCanvas के बिना, किसी वर्कर में Canvas API का इस्तेमाल नहीं किया जा सकता था, क्योंकि कोई DOM उपलब्ध नहीं था.

OffscreenCanvas, DOM पर निर्भर नहीं करता, इसलिए इसका इस्तेमाल किया जा सकता है. इस उदाहरण में, वर्कर्स में ग्रेडिएंट कलर का हिसाब लगाने के लिए, OffscreenCanvas का इस्तेमाल किया गया है:

// file: worker.js
function getGradientColor(percent) {
  const canvas = new OffscreenCanvas(100, 1);
  const ctx = canvas.getContext('2d');
  const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
  gradient.addColorStop(0, 'red');
  gradient.addColorStop(1, 'blue');
  ctx.fillStyle = gradient;
  ctx.fillRect(0, 0, ctx.canvas.width, 1);
  const imgd = ctx.getImageData(0, 0, ctx.canvas.width, 1);
  const colors = imgd.data.slice(percent * 4, percent * 4 + 4);
  return `rgba(${colors[0]}, ${colors[1]}, ${colors[2]}, ${colors[3]})`;
}

getGradientColor(40);  // rgba(152, 0, 104, 255 )

मुख्य थ्रेड को अनब्लॉक करना

ज़्यादा कन्वर्ज़न की गिनती करने के लिए, वर्कर्स को इस्तेमाल करने से, मुख्य थ्रेड के लिए ज़रूरी संसाधनों को खाली किया जा सकता है. रेगुलर कैनवस को OffscreenCanvas इंस्टेंस में मिरर करने के लिए, transferControlToOffscreen तरीका इस्तेमाल करें. OffscreenCanvas पर लागू किए गए ऑपरेशन, सोर्स कैनवस पर अपने-आप रेंडर हो जाएंगे.

const offscreen = document.querySelector('canvas').transferControlToOffscreen();
const worker = new Worker('myworkerurl.js');
worker.postMessage({canvas: offscreen}, [offscreen]);

नीचे दिए गए उदाहरण में, रंग की थीम बदलने पर ज़्यादा कैलकुलेशन की ज़रूरत होती है. यह प्रोसेस, तेज़ डेस्कटॉप पर भी कुछ मिलीसेकंड ले सकती है. आपके पास ऐनिमेशन को मुख्य थ्रेड या वर्कर्स में चलाने का विकल्प होता है. मुख्य थ्रेड के मामले में, ज़्यादा समय लेने वाला टास्क चलने के दौरान, बटन के साथ इंटरैक्ट नहीं किया जा सकता. ऐसा इसलिए होता है, क्योंकि थ्रेड ब्लॉक हो जाती है. वर्कर्स के मामले में, यूज़र इंटरफ़ेस (यूआई) के रिस्पॉन्सिवनेस पर कोई असर नहीं पड़ता.

डेमो

यह दूसरे तरीके से भी काम करता है: व्यस्त मुख्य थ्रेड से, वर्कर्स पर चल रहे ऐनिमेशन पर कोई असर नहीं पड़ता. इस सुविधा का इस्तेमाल करके, विज़ुअल में रुकावट आने से बचा जा सकता है. साथ ही, मुख्य थ्रेड के ट्रैफ़िक के बावजूद, ऐनिमेशन को आसानी से चलाया जा सकता है. इसकी जानकारी, नीचे दिए गए डेमो में दी गई है.

डेमो

सामान्य कैनवस के मामले में, जब मुख्य थ्रेड पर बहुत ज़्यादा काम करने के लिए कहा जाता है, तो ऐनिमेशन रुक जाता है. हालांकि, वर्कर्स पर आधारित OffscreenCanvas आसानी से चलता रहता है.

आम तौर पर, OffscreenCanvas API, सामान्य Canvas एलिमेंट के साथ काम करता है. इसलिए, इसका इस्तेमाल प्रगतिशील बेहतर बनाने के तौर पर किया जा सकता है. साथ ही, इसे मार्केट की कुछ प्रमुख ग्राफ़िक लाइब्रेरी के साथ भी इस्तेमाल किया जा सकता है.

उदाहरण के लिए, इसकी सुविधा का पता लगाया जा सकता है. अगर यह उपलब्ध है, तो रेंडरर कंस्ट्रक्टर में कैनवस विकल्प तय करके, Three.js के साथ इसका इस्तेमाल किया जा सकता है:

const canvasEl = document.querySelector('canvas');
const canvas =
  'OffscreenCanvas' in window
    ? canvasEl.transferControlToOffscreen()
    : canvasEl;
canvas.style = {width: 0, height: 0};
const renderer = new THREE.WebGLRenderer({canvas: canvas});

यहां एक बात ध्यान रखें कि Three.js को कैनवस में style.width और style.height प्रॉपर्टी की ज़रूरत होती है. OffscreenCanvas, DOM से पूरी तरह से अलग है. इसलिए, आपको इसे खुद उपलब्ध कराना होगा. इसके लिए, इसे स्टब करके या ऐसा लॉजिक देकर उपलब्ध कराया जा सकता है जो इन वैल्यू को ओरिजनल कैनवस डाइमेंशन से जोड़ता हो.

यहां, वर्कर्स में बुनियादी Three.js ऐनिमेशन चलाने का तरीका बताया गया है:

डेमो

ध्यान रखें कि DOM से जुड़े कुछ एपीआई, वर्कर्स में आसानी से उपलब्ध नहीं होते. इसलिए, अगर आपको टेक्सचर जैसी Three.js की ज़्यादा बेहतर सुविधाओं का इस्तेमाल करना है, तो आपको कुछ और तरीके आज़माने पड़ सकते हैं. इन सुविधाओं को आज़माने के बारे में कुछ आइडिया पाने के लिए, Google I/O 2017 का वीडियो देखें.

अगर कैनवस की ग्राफ़िक क्षमताओं का ज़्यादा इस्तेमाल किया जा रहा है, तो OffscreenCanvas आपके ऐप्लिकेशन की परफ़ॉर्मेंस पर सकारात्मक असर डाल सकता है. वर्कर्स के लिए कैनवस रेंडरिंग कॉन्टेक्स्ट उपलब्ध कराने से, वेब ऐप्लिकेशन में पैरलल प्रोसेसिंग बढ़ती है. साथ ही, मल्टी-कोर सिस्टम का बेहतर तरीके से इस्तेमाल किया जा सकता है.

अन्य संसाधन