AfterPack performance: मापी गई speed और size

AfterPack एक build और एक page पर कितना खर्च डालता है: 185 KB bundle पर मापा गया obfuscation time, wasm build का time और download size, हर preset का output size, page का startup समय और runtime लागत, protected code को host global पढ़ने की कीमत, और नया seed caching पर क्या असर डालता है।

इस पेज की हर संख्या मापी गई है, अनुमानित नहीं। जब तक कोई table कुछ और न बताए, मशीन एक Apple M2 Max, 32 GB RAM, macOS 26.6.2 थी। यहाँ किसी दूसरे tool से कोई तुलना नहीं है।

इनमें से ज़्यादातर के पीछे का fixture next16_framework_runtime है: framework runtime का 185 KB, जिसे एक असली Next.js 16 build ship करती है। यह एक पहले से minified production bundle है, और AfterPack असल में इसी आकार के input पर चलता है।

Build का समय

2026-09-29 को, ऊपर बताई मशीन पर, AfterPack 0.2.0 के साथ डिफ़ॉल्ट light preset पर मापा गया।

क्या चलाInputसमयThroughput
npm package, 185 KB bundle पर185 KB229 ms0.79 MB/s
अकेला engine, वही bundle185 KB243 ms0.74 MB/s
npm package, 766 KB की multi-file build पर766 KB1,362 ms0.55 MB/s

योजना बनाने के लिए npm वाली row देखें। यह published package है जो वही काम उसी तरह करता है जैसे एक plugin या npx afterpack@latest करते हैं, इसलिए इसमें आपके code को engine में ले जाने और वापस लाने की लागत शामिल है। Engine वाली row वही bundle है, उसी preset पर, बिना उस लागत के, और उसे एक अलग harness से मापा गया। दोनों एक-दूसरे से 15 ms के भीतर हैं, इसलिए packaging कोई मापने योग्य लागत नहीं जोड़ती।

Engine वाली row पर peak memory एक अकेली 185 KB फ़ाइल के लिए baseline से 20.8 MB ऊपर थी। 766 KB वाले multi-file run ने अपने अधिकतम बिंदु पर 76 MB रखे।

Obfuscation एक post-build चरण है, इसलिए यह समय आपकी build में जुड़ता है, आपके users के page load में नहीं। डिफ़ॉल्ट preset पर लागत का आकार यही है: 766 KB की build लगभग 1.4 सेकंड में; ऊँचे preset की लागत ज़्यादा होती है।

Wasm build

@afterpack/wasm वही engine है जो WebAssembly में compile किया गया है, Cloudflare Worker के लिए, Node के लिए, और इस साइट के playground के लिए।

समय, preset के हिसाब सेNode 24
110 KB bundle, light147 ms
185 KB bundle, light237 ms
185 KB bundle, medium1,011 ms
185 KB bundle, extreme2,603 ms

हर समय चालू Protection Map के साथ नौ runs का median है, जो 2026-10-17 को @afterpack/wasm 0.2.6 के साथ ऊपर बताई मशीन पर मापा गया। 110 KB bundle उसी Next.js 16 build का polyfills chunk है।

Download raw रूप में 4.36 MiB और gzipped रूप में 1.25 MiB है। यह हर Worker isolate या हर browser tab में एक बार होता है, हर build पर नहीं।

यह speed लागू की जाती है: एक CI check 185 KB fixture पर extreme preset और चालू Protection Map के साथ engine का समय मापता है, उसी run में एक pinned reference engine के साथ-साथ, और अगर engine का सबसे तेज़ run reference से 13.5 गुना से ज़्यादा समय ले, तो build fail कर देता है।

Wasm native build से धीमा चलता है, और उसकी speed एक सोचा-समझा trade-off है: पहले की एक size के लिए optimised build gzipped रूप में 39% छोटी और 2.1x धीमी निकली, जिसने एक असली 66-फ़ाइल build को cloud engine की deadline से आगे धकेल दिया। Speed जीती।

ये laptop के समय हैं, Cloudflare के नहीं। Cloudflare के network पर Worker isolate के पास कम CPU, ठंडा cache और हर request की CPU सीमा होती है, इसलिए वही input वहाँ इस table से ज़्यादा समय लेता है। इन संख्याओं के आधार पर budget तय करने से पहले उसी platform पर मापें जिस पर आप चलाएँगे।

Output का size

Obfuscation bytes जोड़ता है। 2026-10-16 को AfterPack 0.2.6 के साथ, पाँच fixtures पर (ऊपर वाला 185 KB runtime, Next.js 16 के दो और chunks, एक Vite React bundle और एक PostHog chunk), हर preset के लिए, उसी फ़ाइल के minified रूप की तुलना में gzipped output पर मापा गया:

PresetGzipped output multiplier
minify1.09x से 1.17x
light1.29x से 1.60x
medium6.04x से 8.33x
hard6.62x से 9.23x
extreme8.25x से 11.19x

हर range fixtures के बीच का फैलाव है, कोई confidence interval नहीं, और यह preset के साथ लगातार बढ़ता है।

complexity target output size तय करता है; ये ranges हर preset से असल में मिले output की माप हैं। जब आप चाहें कि build आपकी चुनी size से आगे बढ़ने के बजाय विफल हो जाए, तो स्पष्ट रूप से inflation.max सेट करें; देखें Presets।

छोटी फ़ाइलें इनमें से किसी से भी अनुपात में बड़ी निकलती हैं, क्योंकि हर output में engine का निश्चित runtime overhead होता है। अनुपात किसी असली bundle पर पढ़ें।

Page load

भारी preset page को शुरू होने में धीमा बनाता है, क्योंकि page के respond करने से पहले browser ज़्यादा code parse करता और चलाता है। 2026-10-24 को AfterPack 1.0.0 के साथ, ऊपर बताई मशीन पर, headless Chromium में मापा गया: AfterPack plugins के end-to-end tests से पाँच छोटे apps, हर एक को एक बार बिना AfterPack के और हर preset के लिए एक बार पूरे bundle को उस preset पर रखकर build किया गया, और localhost से serve किया गया, इसलिए इसमें network का कोई समय शामिल नहीं है। हर आंकड़ा navigation से लेकर app के counter पर उस पहले click तक का समय है जो उसे बदलता है, पाँच cold loads का median, हर load एक नए browser context में।

AppAfterPack के बिनाlightmediumhardextreme
Vite और React35 ms52 ms253 ms295 ms596 ms
Vite पर Vue31 ms36 ms176 ms117 ms199 ms
Astro islands44 ms48 ms205 ms249 ms622 ms
SvelteKit27 ms32 ms84 ms89 ms162 ms
Next.js, webpack42 ms74 ms462 ms573 ms1,010 ms
Next.js, webpack, CPU 4x throttle किया गया145 ms234 ms1,652 ms2,215 ms3,844 ms

आख़िरी row Chromium के CPU को चार गुना धीमा करती है, जो एक mid-range phone का मोटा अनुमान है।

Protection से पहले, pages 168 KB से 453 KB JavaScript load करते हैं। हर app पर size लगभग एक ही गुणक से बढ़ता है (Presets में अनुपात हैं); startup समय इस हिसाब से बढ़ता है कि उस code का कितना हिस्सा पहले click से पहले चलता है। medium पर main-thread script समय Vue पर unprotected build का 4.5x और Next.js पर 14.7x था। Framework का अपना runtime हर bundle का हिस्सा है, और हर preset उसे भी protect करता है।

light पर, पहला काम करने वाला click 4 ms से 32 ms देर से आया। medium और ऊपर, preset को पूरे bundle पर ship करने से पहले अपने pages ख़ुद मापें; Presets बताता है कि हर tier आपको क्या scope करने देता है।

Runtime लागत

Protected code मूल से धीमा चलता है, और लागत preset के साथ बढ़ती है। AfterPack 0.2.4 के साथ self-hosted x86_64 CI runner पर, Node 22 में मापा गया: चार tight-loop programs, हर आंकड़ा protected run time बटा मूल का run time, चारों का median।

Presetमूल की तुलना में run time
minify1.0x
light2.1x
medium32.5x
hard35.0x
extreme37.3x

ये सबसे बुरी स्थितियाँ हैं: ये loops protected arithmetic के अलावा कुछ नहीं करते, और सामान्य app code ऐसे loops में बहुत कम समय बिताता है। अगर किसी preset का median यहाँ के आंकड़े के 2.5 गुना से ऊपर जाता है, तो एक CI check engine को fail कर देता है।

एक hot numeric kernel, जैसे image filter, physics step या parser का inner loop, लगभग पूरा आंकड़ा चुकाता है। Pro key के साथ, उसे region preset से light पर रखें और बाकी bundle को अपने global preset पर छोड़ दें। Free build कम region preset को ignore करती है, इसलिए Free पर, जब hot kernel मायने रखता हो, global preset को light पर रखें।

Host globals को पढ़ना

Protected code URL जैसे host global को एक check के ज़रिए पढ़ता है, जो वह global मौजूद न होने पर आपके original code जैसा ही ReferenceError throw करता है। इस check की लागत इस पर निर्भर करती है कि code कहाँ चलता है।

2026-10-13 को AfterPack 0.2.4 के साथ, एक arm64 Mac पर Node 24 में, ऐसे loop से मापा गया जो हर iteration में URL एक बार पढ़ता है। हर आँकड़ा protected build का run time है, जिसे उसी protected build के उस run time से भाग दिया गया है जो global को बिना check के पढ़ता है। हर range दो seeds को कवर करती है, और हर seed 5 से 7 interleaved rounds में सबसे तेज़ round है।

Presetसामान्य contextnode:vm के अंदर
light1.00x2.7x
medium1.06x से 1.13x2.0x से 2.1x
hard1.04x से 1.05x1.9x से 2.1x
extreme1.10x से 1.18x2.0x से 2.1x

सामान्य context का मतलब है browser page, worker या Node का main context; यह column एक Node worker thread में मापा गया। वहाँ light पर check की कोई मापने लायक लागत नहीं है। medium से ऊपर, preset की जोड़ी गई protection check को घेर लेती है, और उसकी लागत हर read पर लगती है।

node:vm context अपने global object पर हर lookup को एक callback से गुज़ारता है, इसलिए वहाँ वही loop बिना check के मुकाबले 1.9x से 2.7x समय लेता है। जो test या benchmark protected code को node:vm के अंदर चलाता है, वह यह लागत उसकी ऊपरी सीमा पर देखता है, इसलिए hot loop में host globals पढ़ने वाले code को वहीं मापें जहाँ आपके users उसे चलाते हैं।

Releases के बीच caching

नया seed हर protected chunk के bytes बदल देता है, उन chunks के भी जिनका source नहीं बदला। Bundler plugins seed को हर chunk के file name में शामिल करते हैं, इसलिए हर release के बाद लौटने वाले visitors सारा protected JavaScript फिर से download करते हैं। Fixed seed बिना बदले chunk को byte-दर-byte एक जैसा और cached रखता है, और तब वह chunk releases के बीच अपनी बनावट भी बनाए रखता है। Next.js, Angular, Vite या webpack output पर CLI content-hashed files का नाम plugins की तरह ही बदलता है; बाकी output पर नाम वही रहते हैं, इसलिए वहाँ seed pin करें या उस output को छोटी cache lifetime दें। देखें File names और caching।

आगे

  • Presets: हर preset कौन-सा size budget तय करता है, और उसे बढ़ाने की लागत क्या है।
  • Build & CI: pipeline में यह चरण कहाँ रखें।
  • Cloudflare Workers: wasm build को एक isolate में चलाना।
  • Playground: wasm build, आपके browser में चलती हुई और अपना समय खुद मापती हुई।