ब्राउज़र JavaScript timers को throttle क्यों करते हैं
(nolanlawson.com)- JavaScript में
setTimeout(0)वास्तव में तुरंत execute नहीं होता और अक्सर कम से कम 4ms की देरी के साथ चलता है; यह दुरुपयोग रोकने के लिए ब्राउज़र की डिफ़ॉल्ट सीमा है - ऐसे प्रतिबंध इसलिए लगाए जाते हैं ताकि वेबसाइटें timers का अंधाधुंध दुरुपयोग करके बैटरी खपत या interaction performance में गिरावट न पैदा करें; battery mode में यह सीमा 16ms और background tab में 1 सेकंड तक और कड़ी हो सकती है
- डेवलपर्स ने
setTimeoutकी सीमाओं से बचने के लिएsetImmediate,MessageChannel.postMessage,window.postMessage,scheduler.postTaskजैसे कई वैकल्पिक timer API का उपयोग किया है - वास्तविक benchmark के अनुसार Chrome और Firefox में 4ms clamping लागू होती है, लेकिन
MessageChannelऔरscheduler.postTaskलगभग बिना देरी के काम करते हैं; Safari मेंsetTimeoutपर और कड़ा प्रतिबंध देखने को मिलता है - मूल रूप से यह user experience की सुरक्षा और developer freedom के बीच संतुलन का सवाल है; फिलहाल Scheduler API एक standardized समाधान के रूप में उभर चुका है, लेकिन दुरुपयोग होने पर नया browser intervention भी आ सकता है
setTimeout सीमा की पृष्ठभूमि
setTimeout(0)होने पर भी abuse के कारण वास्तविक execution अक्सर कम से कम 4ms बाद होता हैconst start = performance.now() setTimeout(() => { // लगभग 4ms बाद execute होता है console.log(performance.now() - start) }, 0)- इसका उद्देश्य अनियंत्रित repeated calls को रोककर battery usage और rendering delay को कम करना है
- कुछ ब्राउज़र environment के अनुसार इस सीमा को और सख्त करते हैं
- battery mode: पुराने Edge में 16ms
- background tab: Chrome में अधिकतम 1 सेकंड तक देरी
दूसरे timer API का आगमन
setImmediate: केवल IE और पुराने Edge में supported, अब लगभग समाप्तMessageChannel.postMessage: अलग channel के माध्यम से event loop में task भेजता हैwindow.postMessage: performance अच्छी है, लेकिन दूसरे scripts के साथ टकराव का जोखिम हैscheduler.postTask: modern browsers में supported और सबसे स्थिर विकल्प माना जाता है
benchmark परिणाम (MacBook Pro 2021, 101 बार माप)
- Chrome 139:
setTimeout4.2ms,scheduler.postTask0ms - Firefox 142:
setTimeout4.72ms,scheduler.postTask0.01ms - Safari 18.4:
setTimeout26.73ms,MessageChannel0.52ms,window.postMessage0.05ms
fake-indexeddb का मामला
- IndexedDB event loop की microtask समाप्ति के तुरंत बाद transaction का automatic commit चाहता है
- Node.js का
setImmediateआदर्श है, लेकिन ब्राउज़र मेंsetTimeoutअप्रभावी है - Chrome में 300ms लगने वाला काम ब्राउज़र में बढ़कर 4.8 सेकंड तक पहुँचने की समस्या आई
- समाधान के रूप में
scheduler.postTaskको default बनाया गया, और compatibility के लिएMessageChannel/window.postMessageको fallback के तौर पर अपनाया गया
browser intervention पर बहस
- एक पक्ष का तर्क है कि timers पर सीमा होनी चाहिए ताकि डेवलपर्स खुद को नुकसान पहुँचाने से बच सकें
- दूसरा पक्ष कहता है कि डेवलपर्स को खुद मापने और optimize करने की स्वतंत्रता मिलनी चाहिए
- अंततः user-first सिद्धांत के तहत ब्राउज़र दुरुपयोग रोकने के लिए intervention करते हैं
- Scheduler API इन दोनों पक्षों के बीच समझौता करता है: यह डेवलपर्स को बारीक task control देता है और साथ ही ब्राउज़र rendering pipeline के साथ alignment में डिज़ाइन किया गया है
आगे की दिशा
postTaskऔरpostMessageफिलहाल बिना throttling के बने रहने की संभावना है- लेकिन
user-blockingजैसी high priority का दुरुपयोग हुआ तो फिर से intervention संभव है - लंबे समय में
scheduler2जैसी किसी और वैकल्पिक API की ज़रूरत पड़ सकती है
अभी कोई टिप्पणी नहीं है.