Boost Qiankun Sandbox Performance 10x by Changing Just 3 Characters
This article explains how a tiny change—replacing three var declarations with const inside qiankun's sandbox—delivers over tenfold performance gains in micro‑frontend scenarios, backed by code examples and real‑world benchmark results.
Indeed Slow, But Not Too Much 🤪
Since its release, qiankun2 has been criticized for being slow, but in most cases the impact is negligible; the real slowdown usually comes from large bundles, long API responses, or inflexible UI.
CPU‑intensive UI operations such as charts or massive DOM changes (>1000) can cause noticeable jank, leading many to disable the sandbox for better performance.
Restarting the Optimization Journey 😤
Inspired by community feedback, we revisited the sandbox performance issue.
Sandbox Core Idea
const windowProxy = new Proxy(window, traps);
with (windowProxy) {
// application code runs against the proxy
${appCode}
}The main bottleneck was frequent accesses to global variables via the sandbox, e.g., Symbol.unscopables, which can reach tens of millions of calls in chart scenarios.
To reduce proxy lookups we cache globals before the with block.
const windowProxy = new Proxy(window, traps);
with (windowProxy) {
// cache globals
var undefined = windowProxy.undefined;
var Array = windowProxy.Array;
var Promise = windowProxy.Promise;
${appCode}
}Initial tests on Windows showed no measurable improvement.
After realizing that var declarations still reside in the outer lexical environment, we switched them to const:
const windowProxy = new Proxy(window, traps);
with (windowProxy) {
// cache globals with const
const undefined = windowProxy.undefined;
const Array = windowProxy.Array;
const Promise = windowProxy.Promise;
${appCode}
}This tiny change yielded dramatic speedups.
Scenario 1: Large Checkbox List in Vue
With the sandbox enabled, the timing matches native performance.
Scenario 2: 10,000 DOM Inserts/Updates
Vue event handler performs a loop inserting/updating 10,000 DOM nodes.
<template>
<div class="pt60">
<ul class="wrapper">
<li v-for="item in aaa" :key="item">{{ item }}</li>
</ul>
<button @click="test">test</button>
</div>
</template>
<script>
import logo from "@/assets/logo.png";
export default {
data() {
return { aaa: 1 };
},
methods: {
test() {
console.time("run loop", 10000);
for (let index = 2; index < 1 * 10000; index++) {
this.aaa = index;
}
console.timeLog("run loop", 10000);
this.$nextTick(() => {
console.timeEnd("run loop", 10000);
});
}
}
};
</script>The optimization reduces the time by more than 50×, comparable to native execution.
How It Works 🧙
The key was replacing var with const inside the with block, allowing the variables to be stored in the block’s lexical environment instead of the global one, thus avoiding proxy lookups.
One More Thing 😂
Before blaming micro‑frontend frameworks for poor performance, consider:
Is the bundle size unreasonable?
Are heavy pre‑load dependencies blocking rendering?
Is the micro‑app loading strategy suboptimal?
Is there a missing loading animation causing a white screen?
Alipay Experience Technology
Exploring ultimate user experience and best engineering practices
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
