• 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: setTimeout 4.2ms, scheduler.postTask 0ms
  • Firefox 142: setTimeout 4.72ms, scheduler.postTask 0.01ms
  • Safari 18.4: setTimeout 26.73ms, MessageChannel 0.52ms, window.postMessage 0.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 की ज़रूरत पड़ सकती है

अभी कोई टिप्पणी नहीं है.

अभी कोई टिप्पणी नहीं है.