WebAssembly सुविधा का पता लगाने की सुविधा

सभी ब्राउज़र पर उपयोगकर्ताओं की मदद करने के साथ-साथ, WebAssembly की नई सुविधाओं को इस्तेमाल करने का तरीका जानें.

WebAssembly 1.0 को चार साल पहले रिलीज़ किया गया था. इसके बावजूद, इसके डेवलपमेंट में कुछ नहीं हुआ. नई सुविधाएं, सुझाव के लिए स्टैंडर्ड प्रोसेस के ज़रिए जोड़ी जाती हैं. जैसा कि वेब पर नई सुविधाओं के साथ आम तौर पर होता है, उन्हें लागू करने का क्रम और समयावधि, अलग-अलग इंजन के लिए काफ़ी अलग हो सकती है. अगर आपको उन नई सुविधाओं का इस्तेमाल करना है, तो आपको यह पक्का करना होगा कि आपके सभी उपयोगकर्ता छूट न जाएं. इस लेख में, इसे हासिल करने का तरीका बताया गया है.

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

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

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

चुनने और उनके ग्रुप बनाने की सुविधाएं

आइए, उदाहरण के तौर पर कुछ आर्बिट्रेरी फ़ीचर सेट को चुनकर इन चरणों के बारे में जानते हैं. मान लें कि मुझे पता चला है कि मुझे साइज़ और परफ़ॉर्मेंस की वजह से, लाइब्रेरी में सिमडी, थ्रेड, और अपवाद मैनेज करने के तरीके का इस्तेमाल करना है. उपयोगकर्ताओं को ब्राउज़र की यह सुविधा मिलती है:

चुनी गई सुविधाओं के लिए ब्राउज़र पर काम करने की सुविधा दिखाने वाली टेबल.
webassembly.org/roadmap पर सुविधाओं की यह टेबल देखें.

ब्राउज़र को नीचे दिए गए कोहॉर्ट में बांटा जा सकता है, ताकि यह पक्का किया जा सके कि हर उपयोगकर्ता को सबसे बेहतर अनुभव मिले:

  • Chrome पर आधारित ब्राउज़र: थ्रेड, सिमडी, और अपवाद मैनेज करने वाले ये सभी ब्राउज़र इस्तेमाल किए जा सकते हैं.
  • Firefox: Thread और SIMD का इस्तेमाल नहीं किया जा सकता, लेकिन अपवाद को हैंडल करने की सुविधा नहीं है.
  • Safari: थ्रेड काम करते हैं, SIMD और अपवाद हैंडलिंग नहीं.
  • अन्य ब्राउज़र: सिर्फ़ बेसलाइन WebAssembly पर काम करने वाले ब्राउज़र हैं.

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

अलग-अलग सुविधाओं के सेट के लिए कंपाइल किया जा रहा है

WebAssembly में रनटाइम में काम करने वाली सुविधाओं का पता लगाने का कोई तरीका मौजूद नहीं है. इसलिए, मॉड्यूल में मौजूद सभी निर्देश टारगेट पर काम करने चाहिए. इस वजह से, आपको हर अलग सुविधा सेट के लिए सोर्स कोड को अलग-अलग Wasm में इकट्ठा करना होगा.

हर टूलचेन और बिल्ड सिस्टम अलग-अलग होता है. इन सुविधाओं में बदलाव करने का तरीका जानने के लिए, आपको अपने कंपाइलर का दस्तावेज़ देखना होगा. आसानी के लिए, नीचे दिए गए उदाहरण में एक फ़ाइल वाली C++ लाइब्रेरी का इस्तेमाल किया जाएगा और दिखाया जाएगा कि उसे Emscripten से कैसे कंपाइल किया जाता है.

मैं एसएसई2 एम्युलेशन के ज़रिए सिमडी और Pथ्रेड लाइब्रेरी सहायता के ज़रिए थ्रेड का इस्तेमाल करूंगा/करूंगी, और वेब अपवाद को मैनेज करना और फ़ॉलबैक JavaScript लागू करना में से किसी एक को चुनूंगा:

# First bundle: threads + SIMD + Wasm exceptions
$ emcc main.cpp -o main.threads-simd-exceptions.mjs -pthread -msimd128 -msse2 -fwasm-exceptions
# Second bundle: threads + SIMD + JS exceptions fallback
$ emcc main.cpp -o main.threads-simd.mjs -pthread -msimd128 -msse2 -fexceptions
# Third bundle: threads + JS exception fallback
$ emcc main.cpp -o main.threads.mjs -pthread -fexceptions
# Fourth bundle: basic Wasm with JS exceptions fallback
$ emcc main.cpp -o main.basic.mjs -fexceptions

C++ कोड, #ifdef __EMSCRIPTEN_PTHREADS__ और #ifdef __SSE2__ का इस्तेमाल करके, एक जैसे फ़ंक्शन को पैरलल (थ्रेड और SIMD) और कंपाइल करते समय, सीरियल को लागू करने के तरीके के बीच शर्त के हिसाब से चुन सकता है. यह ऐसा दिखेगा:

void process_data(std::vector<int>& some_input) {
#ifdef __EMSCRIPTEN_PTHREADS__
#ifdef __SSE2__
  // …implementation using threads and SIMD for max speed
#else
  // …implementation using threads but not SIMD
#endif
#else
  // …fallback implementation for browsers without those features
#endif
}

अपवाद को हैंडल करने के लिए #ifdef डायरेक्टिव की ज़रूरत नहीं होती है, क्योंकि C++ में भी इसका इस्तेमाल उसी तरह किया जा सकता है, भले ही कंपाइलेशन फ़्लैग के ज़रिए कोई भी लागू किया गया हो.

सही बंडल लोड किया जा रहा है

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

import { simd, threads, exceptions } from 'https://unpkg.com/wasm-feature-detect?module';

let initModule;
if (await threads()) {
  if (await simd()) {
    if (await exceptions()) {
      initModule = import('./main.threads-simd-exceptions.mjs');
    } else {
      initModule = import('./main.threads-simd.mjs');
    }
  } else {
    initModule = import('./main.threads.mjs');
  }
} else {
  initModule = import('./main.basic.mjs');
}

const Module = await initModule();
// now you can use `Module` Emscripten object like you normally would

अंतिम शब्द

इस पोस्ट में, मैंने अलग-अलग फ़ीचर सेट के लिए, बंडल चुनने, बनाने, और उनके बीच स्विच करने का तरीका बताया है.

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

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