Turbolog: झिलमिलाहट हटाना
हर फ़्रेम से पहले कंसोल साफ़ करने पर वह DevTools के 70–81% पेंट में खाली दिखता था। फ़्रेम जोड़ने से यह 1% रह गया, और वह भी सिर्फ़ पहले फ़्रेम पर।
Text.js का हर फ़्रेम एक console.log कॉल है। 0.4 तक, हर फ़्रेम से पहले console.clear() कॉल भी होती थी। लोड बढ़ने पर, फ़्रेम के बीच कंसोल खाली होकर झिलमिलाता था।
झिलमिलाहट का मापन
इसे मापने के लिए, हमने bench/devtools बनाया। यह Chrome for Testing लॉन्च करता है, असली DevTools फ़्रंटएंड को एक पेज के रूप में खोलता है और उसमें मापन की व्यवस्था करता है:
- DevTools फ़्रंटएंड में हर
requestAnimationFrameपर, यह जांचता है कि कंसोल व्यूपोर्ट में 32 पंक्तियों का पूरा फ़्रेम है या नहीं। जिन पेंट में ऐसा फ़्रेम नहीं होता, वे खाली पेंट हैं। - नतीजे की पिक्सल में पुष्टि करने के लिए यह बाद में
Page.startScreencastफ़्रेम डिकोड करता है। - हर फ़्रेम की पंक्ति 0 में
FRAME:<id> · T:<epochMs>होता है, ताकि फ़्रंटएंड पहचान सके कि वह कौन-सा फ़्रेम दिखा रहा है और उसमें कितनी देरी है।
हर फ़्रेम से पहले console.clear() कॉल करने पर, 15 fps पर चल रहा 100×32 डैशबोर्ड DevTools के 70.6% पेंट में खाली था। 60 fps पर, 81.1%।
वजह
DevTools का ConsoleView दोनों कॉल को अलग-अलग तरीके से संभालता है:
console.clear()सेconsoleCleared()कॉल होता है, जो व्यूपोर्ट को सिंक्रोनस तरीके से इनवैलिडेट करता है। उसी टास्क में हर मैसेज गायब हो जाता है।console.log()सेaddConsoleMessage()कॉल होता है, जो सिर्फ़viewportThrottlerके ज़रिए रिफ़्रेश शेड्यूल करता है, जो 50 ms टाइमआउट वालाThrottlerहै।
इसलिए हर फ़्रेम पुराने फ़्रेम को तुरंत हटाता है और नए को बाद में पेंट करता है। 15 fps पर, हर 66 ms में से लगभग 50 ms तक कुछ नहीं दिखता।
फ़्रेम जोड़ना
0.4 से, Turbolog फ़्रेम जोड़ता है। DevTools कंसोल के सबसे नीचे टिका रहता है, इसलिए एक ही पेंट में नया फ़्रेम पुराने की जगह ले लेता है। शुरुआत में मौजूद margin-top:100vh वाला शून्य-चौड़ाई का span (पर्दा) पहले के फ़्रेम को नज़र से बाहर धकेलता है, और अपनी लाइन वहीं समाप्त करता है ताकि DevTools का सोर्स लिंक कभी पंक्ति 0 को संकरा न करे।
आख़िरकार कंसोल को खाली करना फिर भी ज़रूरी है। कंसोल सिर्फ़ पहले फ़्रेम पर, invalidate() के बाद, 100 फ़्रेम जमा होने पर आइडल अवस्था में, और 300 की तय अधिकतम सीमा पर साफ़ होता है।
थ्रॉटलर के मुताबिक रफ़्तार
DevTools की पेंट करने की रफ़्तार से तेज़ फ़्रेम भेजने से कुछ भी तेज़ नहीं होता। थ्रॉटलर के पेंडिंग रहने के दौरान आने वाला लॉग उसे फिर से शुरू करता है, इसलिए फ़्रेम छूट जाते हैं: 60 fps पर DevTools ने भेजे गए 295 फ़्रेम में से 67 पेंट किए। Turbolog फ़्रेम के बीच कम से कम 66 ms का अंतर रखता है, यानी लगभग 15 fps, और अंतराल में गुंजाइश होने पर अलग-अलग इनपुट अब भी सिंक्रोनस तरीके से रेंडर करता है।
फ़ेज़ लॉक तोड़ना
कंसोल साफ़ करने से बाद के हर फ़्रेम में लगभग 50 ms की देरी भी जुड़ती थी। कंसोल साफ़ करने के बाद, DevTools एक सिंथेटिक Console was cleared पंक्ति जोड़ता है। यह थ्रॉटलर का तत्काल स्लॉट ले लेती है और अगले फ़्रेम को 50 ms टाइमर पर धकेल देती है, और 66 ms की स्थिर रफ़्तार पर बाद का हर फ़्रेम उसी टाइमर से लॉक रहता है।
अब रेंडरर कंसोल के हर बार साफ़ होने के बाद एक बार 110 ms इंतज़ार करता है। उसके बाद, हर फ़्रेम पिछले रिफ़्रेश के पूरा होने के 50 ms से अधिक समय बाद आता है और DevTools का तत्काल पाथ लेता है। डिस्प्ले की मीडियन देरी 63 ms से 10.4 ms हो गई।
नतीजे
bun bench/devtools/run.ts --strategy=native,clear --fps=15,60 --seconds=5, 100×32 डैशबोर्ड, असली DevTools फ़्रंटएंड:
| ड्राइवर | FPS | खाली पेंट | पेंट किए गए / भेजे गए | देरी p50 |
|---|---|---|---|---|
| हर फ़्रेम पर साफ़ करना | 15 | 70.6% | 70 / 75 | 60.4 ms |
| जोड़ना (1.0) | 15 | 1.0% | 74 / 75 | 10.4 ms |
| हर फ़्रेम पर साफ़ करना | 60 | 81.1% | 45 / 300 | 9.8 ms |
| जोड़ना, बिना रफ़्तार नियंत्रण | 60 | 0.8% | 67 / 295 | 31.2 ms |
बाकी 1% पहला फ़्रेम है, जो जानबूझकर कंसोल साफ़ करता है। उसके खाली पेंट में Console was cleared पंक्ति होती है, खाली कंसोल नहीं।
हर span पर कम प्रॉपर्टी
DevTools के सोर्स में एक और लागत दिखी। यह %c स्टाइल की हर लॉन्गहैंड को हर लाइन रैपर पर कॉपी करता है, इसलिए font: और margin: शॉर्टहैंड हर span पर लगभग 33 प्रॉपर्टी में फैल जाते थे। अब span सिर्फ़ लॉन्गहैंड इस्तेमाल करते हैं, हर एक में लगभग 7, और हेक्स रंगों का इस्तेमाल करते हैं।
जोड़ने वाला मोड Text.js 0.4 में जारी हुआ था, और फ़ेज़-लॉक फ़िक्स 1.0 में जारी हो रहा है। दोनों के लिए ऐप के कोड में बदलाव की ज़रूरत नहीं है।