सभी ब्राउज़र पर उपयोगकर्ताओं को बेहतर अनुभव देने के साथ-साथ, WebAssembly की नई सुविधाओं का इस्तेमाल करने का तरीका जानें.
WebAssembly 1.0 को चार साल पहले रिलीज़ किया गया था, लेकिन इसके डेवलपमेंट पर तब से काम जारी है. नई सुविधाएं, सुझाव को स्टैंडर्ड बनाने की प्रोसेस के ज़रिए जोड़ी जाती हैं. आम तौर पर, वेब पर नई सुविधाओं को लागू करने का क्रम और समयसीमा, अलग-अलग इंजन के बीच काफ़ी अलग-अलग हो सकती है. अगर आपको इन नई सुविधाओं का इस्तेमाल करना है, तो आपको यह पक्का करना होगा कि आपके किसी भी उपयोगकर्ता को इन सुविधाओं का ऐक्सेस न छूटे. इस लेख में, इसे हासिल करने का तरीका बताया गया है.
कुछ नई सुविधाएं, सामान्य ऑपरेशन के लिए नए निर्देश जोड़कर कोड के साइज़ को बेहतर बनाती हैं. कुछ सुविधाएं, परफ़ॉर्मेंस के बेहतर प्राइमिटिव जोड़ती हैं. वहीं, कुछ सुविधाएं डेवलपर के अनुभव और बाकी वेब के साथ इंटिग्रेशन को बेहतर बनाती हैं.
आधिकारिक रिपॉज़िटरी में, प्रस्तावों की पूरी सूची और उनके अलग-अलग चरणों की जानकारी देखी जा सकती है. इसके अलावा, सुविधा के रोडमैप के आधिकारिक पेज पर जाकर, इंजन में उनके लागू होने की स्थिति को ट्रैक किया जा सकता है.
यह पक्का करने के लिए कि सभी ब्राउज़र के उपयोगकर्ता आपके ऐप्लिकेशन का इस्तेमाल कर सकें, आपको यह तय करना होगा कि आपको किन सुविधाओं का इस्तेमाल करना है. इसके बाद, उन्हें ब्राउज़र के हिसाब से ग्रुप में बांटें. इसके बाद, उन सभी ग्रुप के लिए कोडबेस को अलग-अलग कंपाइल करें. आखिर में, ब्राउज़र की ओर से आपको उन सुविधाओं का पता लगाना होगा जो काम करती हैं. साथ ही, उनसे जुड़े JavaScript और Wasm बंडल को लोड करना होगा.
चुनने और उनके ग्रुप बनाने की सुविधाएं
आइए, उदाहरण के तौर पर कोई सुविधा चुनकर, इन चरणों को पूरा करने का तरीका जानें. मान लें कि मैंने यह तय किया है कि मुझे लाइब्रेरी में साइज़ और परफ़ॉर्मेंस की वजहों से, SIMD, थ्रेड, और अपवाद मैनेजमेंट का इस्तेमाल करना है. इन ब्राउज़र पर यह सुविधा काम करती है:
ब्राउज़र को इन कोहॉर्ट में बांटा जा सकता है, ताकि यह पक्का किया जा सके कि हर उपयोगकर्ता को सबसे ऑप्टिमाइज़ किया गया अनुभव मिले:
- Chrome पर आधारित ब्राउज़र: थ्रेड, SIMD, और अपवाद मैनेजमेंट, सभी काम करते हैं.
- Firefox: थ्रेड और SIMD काम करते हैं, लेकिन अपवाद मैनेज करने की सुविधा काम नहीं करती.
- Safari: थ्रेड काम करते हैं, लेकिन SIMD और अपवाद मैनेजमेंट काम नहीं करते.
- अन्य ब्राउज़र: सिर्फ़ बेसलाइन WebAssembly पर काम करते हैं.
यह ब्रेकडाउन, हर ब्राउज़र के नए वर्शन में सुविधा के हिसाब से बांटा गया है. मॉडर्न ब्राउज़र हमेशा अप-टू-डेट रहते हैं और अपने-आप अपडेट होते रहते हैं. इसलिए, ज़्यादातर मामलों में आपको सिर्फ़ नए वर्शन की चिंता करनी होती है. हालांकि, जब तक फ़ॉलबैक कोहॉर्ट के तौर पर बेसलाइन WebAssembly को शामिल किया जाता है, तब तक पुराने ब्राउज़र का इस्तेमाल करने वाले उपयोगकर्ताओं को भी काम करने वाला ऐप्लिकेशन उपलब्ध कराया जा सकता है.
अलग-अलग सुविधाओं के सेट के लिए कंपाइल करना
WebAssembly में, रनटाइम में काम करने वाली सुविधाओं का पता लगाने का कोई तरीका नहीं है. इसलिए, मॉड्यूल में मौजूद सभी निर्देश, टारगेट पर काम करने चाहिए. इस वजह से, आपको हर अलग सुविधा सेट के लिए सोर्स कोड को अलग-अलग Wasm में इकट्ठा करना होगा.
हर टूलचेन और बिल्ड सिस्टम अलग होता है. इन सुविधाओं में बदलाव करने के लिए, आपको अपने कंपाइलर के दस्तावेज़ देखना होगा. आसानी से समझाने के लिए, हम यहां एक फ़ाइल वाली C++ लाइब्रेरी का इस्तेमाल करेंगे. साथ ही, Emscripten की मदद से इसे कंपाइल करने का तरीका भी बताएंगे.
मैं SSE2 इम्यूलेशन के ज़रिए SIMD का इस्तेमाल करूंगा. साथ ही, Pthreads लाइब्रेरी के सपोर्ट की मदद से थ्रेड का इस्तेमाल करूंगा. इसके बाद, Wasm एक्ससेप्शन हैंडल करने और फ़ॉलबैक 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 की नई सुविधाओं का इस्तेमाल करके कोड बनाने और लोड करने का यह तरीका ही एकमात्र तरीका है.